reroute-js 0.45.11 → 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 +1175 -431
- package/cli/bin.js.map +33 -24
- 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 +827 -192
- package/core/index.js.map +32 -23
- 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/discovery.d.ts.map +1 -1
- 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/index.d.ts.map +1 -1
- 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 +3 -2
- package/core/src/ssr/lib/index.d.ts.map +1 -1
- 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 +20 -0
- package/core/src/ssr/lib/route-match.d.ts.map +1 -0
- 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 +1072 -276
- package/elysia/index.js.map +37 -27
- 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/og.d.ts.map +1 -1
- 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 +565 -171
- 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 +8 -4
- package/telemetry/react.js.map +2 -2
- package/telemetry/server.d.ts +2 -2
- package/telemetry/server.js +60 -5
- package/telemetry/server.js.map +22 -17
- 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
|
*/
|
|
@@ -15,25 +15,43 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
16
16
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
17
17
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
18
|
+
function __accessProp(key) {
|
|
19
|
+
return this[key];
|
|
20
|
+
}
|
|
21
|
+
var __toESMCache_node;
|
|
22
|
+
var __toESMCache_esm;
|
|
18
23
|
var __toESM = (mod, isNodeMode, target) => {
|
|
24
|
+
var canCache = mod != null && typeof mod === "object";
|
|
25
|
+
if (canCache) {
|
|
26
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
27
|
+
var cached = cache.get(mod);
|
|
28
|
+
if (cached)
|
|
29
|
+
return cached;
|
|
30
|
+
}
|
|
19
31
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
20
32
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
21
33
|
for (let key of __getOwnPropNames(mod))
|
|
22
34
|
if (!__hasOwnProp.call(to, key))
|
|
23
35
|
__defProp(to, key, {
|
|
24
|
-
get: (
|
|
36
|
+
get: __accessProp.bind(mod, key),
|
|
25
37
|
enumerable: true
|
|
26
38
|
});
|
|
39
|
+
if (canCache)
|
|
40
|
+
cache.set(mod, to);
|
|
27
41
|
return to;
|
|
28
42
|
};
|
|
29
43
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
44
|
+
var __returnValue = (v) => v;
|
|
45
|
+
function __exportSetter(name, newValue) {
|
|
46
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
47
|
+
}
|
|
30
48
|
var __export = (target, all) => {
|
|
31
49
|
for (var name in all)
|
|
32
50
|
__defProp(target, name, {
|
|
33
51
|
get: all[name],
|
|
34
52
|
enumerable: true,
|
|
35
53
|
configurable: true,
|
|
36
|
-
set: (
|
|
54
|
+
set: __exportSetter.bind(all, name)
|
|
37
55
|
});
|
|
38
56
|
};
|
|
39
57
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -48,7 +66,7 @@ async function getVersionString() {
|
|
|
48
66
|
}
|
|
49
67
|
async function getVersion() {
|
|
50
68
|
if (true) {
|
|
51
|
-
return "0.
|
|
69
|
+
return "0.46.0";
|
|
52
70
|
}
|
|
53
71
|
const possiblePaths = [
|
|
54
72
|
path.join(import.meta.dir, "../../../../package.json"),
|
|
@@ -66,7 +84,7 @@ async function getVersion() {
|
|
|
66
84
|
}
|
|
67
85
|
async function getCommit() {
|
|
68
86
|
if (true) {
|
|
69
|
-
return "
|
|
87
|
+
return "9116acf";
|
|
70
88
|
}
|
|
71
89
|
return "dev";
|
|
72
90
|
}
|
|
@@ -518,6 +536,364 @@ var init_content = __esm(() => {
|
|
|
518
536
|
init_metadata();
|
|
519
537
|
});
|
|
520
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
|
+
|
|
521
897
|
// packages/telemetry/src/server/context.ts
|
|
522
898
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
523
899
|
var contextStorage;
|
|
@@ -1112,6 +1488,148 @@ function compressStreamIfAccepted(stream, contentType, _acceptEncoding) {
|
|
|
1112
1488
|
}
|
|
1113
1489
|
var init_compression = () => {};
|
|
1114
1490
|
|
|
1491
|
+
// packages/core/src/ssr/lib/route-match.ts
|
|
1492
|
+
function getPatternParts(pattern) {
|
|
1493
|
+
return pattern.split("/").filter(Boolean);
|
|
1494
|
+
}
|
|
1495
|
+
function isDynamicPatternPart(patternPart) {
|
|
1496
|
+
return patternPart.startsWith(":");
|
|
1497
|
+
}
|
|
1498
|
+
function isCatchAllPatternPart(patternPart) {
|
|
1499
|
+
return patternPart.startsWith(":...");
|
|
1500
|
+
}
|
|
1501
|
+
function isCatchAllParamName(paramName) {
|
|
1502
|
+
return paramName.startsWith("...");
|
|
1503
|
+
}
|
|
1504
|
+
function getPatternPartSpecificity(patternPart) {
|
|
1505
|
+
if (isCatchAllPatternPart(patternPart)) {
|
|
1506
|
+
return 2;
|
|
1507
|
+
}
|
|
1508
|
+
if (isDynamicPatternPart(patternPart)) {
|
|
1509
|
+
return 1;
|
|
1510
|
+
}
|
|
1511
|
+
return 0;
|
|
1512
|
+
}
|
|
1513
|
+
function compareRouteSpecificity(a, b) {
|
|
1514
|
+
const aPatternParts = getPatternParts(a.pattern);
|
|
1515
|
+
const bPatternParts = getPatternParts(b.pattern);
|
|
1516
|
+
const aDepth = aPatternParts.length;
|
|
1517
|
+
const bDepth = bPatternParts.length;
|
|
1518
|
+
if (aDepth !== bDepth) {
|
|
1519
|
+
return bDepth - aDepth;
|
|
1520
|
+
}
|
|
1521
|
+
for (let i = 0;i < aPatternParts.length; i++) {
|
|
1522
|
+
const aSpecificity = getPatternPartSpecificity(aPatternParts[i]);
|
|
1523
|
+
const bSpecificity = getPatternPartSpecificity(bPatternParts[i]);
|
|
1524
|
+
if (aSpecificity !== bSpecificity) {
|
|
1525
|
+
return aSpecificity - bSpecificity;
|
|
1526
|
+
}
|
|
1527
|
+
if (aSpecificity === 0 && aPatternParts[i] !== bPatternParts[i]) {
|
|
1528
|
+
return aPatternParts[i].localeCompare(bPatternParts[i]);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
return a.pattern.localeCompare(b.pattern);
|
|
1532
|
+
}
|
|
1533
|
+
function matchCatchAllParam(paramName, patternIndex, patternLength, pathnameParts, pathnameIndex, params) {
|
|
1534
|
+
if (patternIndex !== patternLength - 1 || pathnameIndex >= pathnameParts.length) {
|
|
1535
|
+
return false;
|
|
1536
|
+
}
|
|
1537
|
+
params[paramName.slice(3)] = pathnameParts.slice(pathnameIndex).join("/");
|
|
1538
|
+
return true;
|
|
1539
|
+
}
|
|
1540
|
+
function matchDynamicParam(paramName, pathnameParts, pathnameIndex, params) {
|
|
1541
|
+
const pathnamePart = pathnameParts[pathnameIndex];
|
|
1542
|
+
if (pathnamePart === undefined) {
|
|
1543
|
+
return null;
|
|
1544
|
+
}
|
|
1545
|
+
params[paramName] = pathnamePart;
|
|
1546
|
+
return pathnameIndex + 1;
|
|
1547
|
+
}
|
|
1548
|
+
function matchPatternPart(patternPart, patternIndex, patternLength, pathnameParts, pathnameIndex, params) {
|
|
1549
|
+
if (isDynamicPatternPart(patternPart)) {
|
|
1550
|
+
const paramName = patternPart.slice(1);
|
|
1551
|
+
if (isCatchAllParamName(paramName)) {
|
|
1552
|
+
return matchCatchAllParam(paramName, patternIndex, patternLength, pathnameParts, pathnameIndex, params) ? "catch-all" : null;
|
|
1553
|
+
}
|
|
1554
|
+
return matchDynamicParam(paramName, pathnameParts, pathnameIndex, params);
|
|
1555
|
+
}
|
|
1556
|
+
if (patternPart !== pathnameParts[pathnameIndex]) {
|
|
1557
|
+
return null;
|
|
1558
|
+
}
|
|
1559
|
+
return pathnameIndex + 1;
|
|
1560
|
+
}
|
|
1561
|
+
function matchRoutePattern(pattern, pathname) {
|
|
1562
|
+
const patternParts = getPatternParts(pattern);
|
|
1563
|
+
const pathnameParts = pathname.split("/").filter(Boolean);
|
|
1564
|
+
const params = {};
|
|
1565
|
+
let pathnameIndex = 0;
|
|
1566
|
+
for (let i = 0;i < patternParts.length; i++) {
|
|
1567
|
+
const nextPathnameIndex = matchPatternPart(patternParts[i], i, patternParts.length, pathnameParts, pathnameIndex, params);
|
|
1568
|
+
if (nextPathnameIndex === null) {
|
|
1569
|
+
return null;
|
|
1570
|
+
}
|
|
1571
|
+
if (nextPathnameIndex === "catch-all") {
|
|
1572
|
+
return params;
|
|
1573
|
+
}
|
|
1574
|
+
pathnameIndex = nextPathnameIndex;
|
|
1575
|
+
}
|
|
1576
|
+
return pathnameIndex === pathnameParts.length ? params : null;
|
|
1577
|
+
}
|
|
1578
|
+
function matchRoutes(routes, pathname) {
|
|
1579
|
+
for (const route of routes) {
|
|
1580
|
+
const params = matchRoutePattern(route.pattern, pathname);
|
|
1581
|
+
if (params) {
|
|
1582
|
+
return { route, params };
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
return null;
|
|
1586
|
+
}
|
|
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
|
+
|
|
1115
1633
|
// packages/core/src/ssr/lib/compute/content.ts
|
|
1116
1634
|
function checkStatusCache(statusCacheKey, maxAgeMs) {
|
|
1117
1635
|
if (maxAgeMs <= 0)
|
|
@@ -1164,6 +1682,14 @@ async function handleNonStreamingMode(ssrData, pathname, task, cacheKey, statusC
|
|
|
1164
1682
|
}
|
|
1165
1683
|
return result;
|
|
1166
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
|
+
}
|
|
1167
1693
|
async function computeContentData(pathname, options, searchParams, sharedSsrData) {
|
|
1168
1694
|
const streaming = options.streaming === true;
|
|
1169
1695
|
const ssrData = streaming && sharedSsrData ? sharedSsrData : {};
|
|
@@ -1173,18 +1699,20 @@ async function computeContentData(pathname, options, searchParams, sharedSsrData
|
|
|
1173
1699
|
const maxAge = options.maxAge || 0;
|
|
1174
1700
|
const maxAgeMs = maxAge * 1000;
|
|
1175
1701
|
try {
|
|
1176
|
-
const
|
|
1177
|
-
if (
|
|
1702
|
+
const resolved = resolveContentPathParts(pathname);
|
|
1703
|
+
if (!resolved) {
|
|
1178
1704
|
return { data: ssrData, pendingTasks };
|
|
1179
1705
|
}
|
|
1706
|
+
const parts = [resolved.collection, resolved.name];
|
|
1707
|
+
if (resolved.locale)
|
|
1708
|
+
parts.splice(1, 0, resolved.locale);
|
|
1180
1709
|
const g = globalThis;
|
|
1181
|
-
const
|
|
1182
|
-
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
1710
|
+
const exp = g.__REROUTE_SSR_EXPORTS__?.[resolved.key];
|
|
1183
1711
|
const dataFn = exp?.ssr?.data;
|
|
1184
1712
|
if (typeof dataFn !== "function") {
|
|
1185
1713
|
return { data: ssrData, pendingTasks };
|
|
1186
1714
|
}
|
|
1187
|
-
const cacheKey = `content:${pathname}:${
|
|
1715
|
+
const cacheKey = `content:${pathname}:${resolved.name}:${resolved.locale || ""}`;
|
|
1188
1716
|
const statusCacheKey = `status:${cacheKey}`;
|
|
1189
1717
|
const cachedStatus = checkStatusCache(statusCacheKey, maxAgeMs);
|
|
1190
1718
|
if (cachedStatus && cachedStatus !== 200) {
|
|
@@ -1197,22 +1725,13 @@ async function computeContentData(pathname, options, searchParams, sharedSsrData
|
|
|
1197
1725
|
}
|
|
1198
1726
|
const set = { status: 200 };
|
|
1199
1727
|
const task = createDataTask(dataFn, pathname, parts, searchParams, set, options.headers);
|
|
1200
|
-
|
|
1201
|
-
handleStreamingMode(ssrData, pathname, task, set, cacheKey, statusCacheKey, maxAgeMs, pendingTasks);
|
|
1202
|
-
if (set.status !== 200) {
|
|
1203
|
-
statusOverride = set.status;
|
|
1204
|
-
}
|
|
1205
|
-
} else {
|
|
1206
|
-
await handleNonStreamingMode(ssrData, pathname, task, cacheKey, statusCacheKey, maxAgeMs);
|
|
1207
|
-
if (set.status !== 200) {
|
|
1208
|
-
statusOverride = set.status;
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1728
|
+
statusOverride = await runContentDataTask(streaming, ssrData, pathname, task, set, cacheKey, statusCacheKey, maxAgeMs, pendingTasks) ?? statusOverride;
|
|
1211
1729
|
} catch {}
|
|
1212
1730
|
return { data: ssrData, error, statusOverride, pendingTasks };
|
|
1213
1731
|
}
|
|
1214
1732
|
var init_content2 = __esm(() => {
|
|
1215
1733
|
init_cache();
|
|
1734
|
+
init_content_path();
|
|
1216
1735
|
init_imports();
|
|
1217
1736
|
});
|
|
1218
1737
|
|
|
@@ -1411,7 +1930,8 @@ async function computeRouteData(pathname, clientDir, _cwd, isWatchMode, options,
|
|
|
1411
1930
|
}).catch(() => {}));
|
|
1412
1931
|
};
|
|
1413
1932
|
try {
|
|
1414
|
-
const
|
|
1933
|
+
const resolved = resolveContentPathParts(pathname);
|
|
1934
|
+
const pathnameOnly = (resolved?.routingPathname || pathname).split("?")[0];
|
|
1415
1935
|
const match = typeof routesModule?.matchRoute === "function" ? routesModule.matchRoute(pathnameOnly) : null;
|
|
1416
1936
|
const route = match?.route;
|
|
1417
1937
|
const params = match?.params || {};
|
|
@@ -1574,44 +2094,18 @@ function handleFlattenedResult(entries, set, ctx, cache, setError, setStatus) {
|
|
|
1574
2094
|
}
|
|
1575
2095
|
var init_routes = __esm(() => {
|
|
1576
2096
|
init_cache();
|
|
2097
|
+
init_content_path();
|
|
1577
2098
|
init_imports();
|
|
1578
2099
|
});
|
|
1579
2100
|
|
|
1580
2101
|
// packages/core/src/ssr/lib/compute/index.ts
|
|
1581
|
-
function matchPatternUtil(pattern, pathname) {
|
|
1582
|
-
const patternParts = pattern.split("/").filter(Boolean);
|
|
1583
|
-
const pathnameParts = pathname.split("/").filter(Boolean);
|
|
1584
|
-
if (patternParts.length !== pathnameParts.length) {
|
|
1585
|
-
return null;
|
|
1586
|
-
}
|
|
1587
|
-
const params = {};
|
|
1588
|
-
for (let i = 0;i < patternParts.length; i++) {
|
|
1589
|
-
const patternPart = patternParts[i];
|
|
1590
|
-
const pathnamePart = pathnameParts[i];
|
|
1591
|
-
if (patternPart.startsWith(":")) {
|
|
1592
|
-
params[patternPart.slice(1)] = pathnamePart;
|
|
1593
|
-
} else if (patternPart !== pathnamePart) {
|
|
1594
|
-
return null;
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
return params;
|
|
1598
|
-
}
|
|
1599
2102
|
function createBundledRoutesModule(bundledRoutes, bundledLayouts) {
|
|
1600
2103
|
const bundledNotFoundRoutes = globalThis.__REROUTE_NOT_FOUND_ROUTES__;
|
|
1601
2104
|
return {
|
|
1602
2105
|
routes: bundledRoutes,
|
|
1603
2106
|
layouts: bundledLayouts,
|
|
1604
2107
|
notFoundRoutes: bundledNotFoundRoutes,
|
|
1605
|
-
matchRoute: (pathname) =>
|
|
1606
|
-
for (const route of bundledRoutes) {
|
|
1607
|
-
const pattern = String(route?.pattern || "");
|
|
1608
|
-
const match = matchPatternUtil(pattern, pathname);
|
|
1609
|
-
if (match) {
|
|
1610
|
-
return { route, params: match };
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
return null;
|
|
1614
|
-
}
|
|
2108
|
+
matchRoute: (pathname) => matchRoutes(bundledRoutes, pathname)
|
|
1615
2109
|
};
|
|
1616
2110
|
}
|
|
1617
2111
|
async function loadRoutesModule(cwd, isWatchMode) {
|
|
@@ -1693,33 +2187,31 @@ var init_compute = __esm(() => {
|
|
|
1693
2187
|
});
|
|
1694
2188
|
|
|
1695
2189
|
// packages/core/src/ssr/lib/modules.ts
|
|
1696
|
-
import { readdir as
|
|
2190
|
+
import { readdir as readdir4, stat as stat3 } from "node:fs/promises";
|
|
1697
2191
|
async function importContentModuleForPath(pathname, clientDir, cwd, isWatchMode) {
|
|
1698
2192
|
try {
|
|
1699
|
-
const
|
|
1700
|
-
|
|
1701
|
-
if (parts.length < 2)
|
|
2193
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2194
|
+
if (!resolved)
|
|
1702
2195
|
return null;
|
|
1703
|
-
const collection =
|
|
1704
|
-
const
|
|
1705
|
-
const registryModule = await tryRegistryImport(collection, name, cwd, isWatchMode);
|
|
2196
|
+
const { collection, name, locale } = resolved;
|
|
2197
|
+
const registryModule = await tryRegistryImport(collection, name, cwd, isWatchMode, locale);
|
|
1706
2198
|
if (registryModule)
|
|
1707
2199
|
return registryModule;
|
|
1708
2200
|
const chunkModule = await tryChunkImport(collection, name, cwd, isWatchMode);
|
|
1709
2201
|
if (chunkModule)
|
|
1710
2202
|
return chunkModule;
|
|
1711
|
-
const sourceModule = await trySourceImport(collection, name, clientDir, isWatchMode);
|
|
2203
|
+
const sourceModule = await trySourceImport(collection, name, clientDir, isWatchMode, locale);
|
|
1712
2204
|
if (sourceModule)
|
|
1713
2205
|
return sourceModule;
|
|
1714
2206
|
} catch {}
|
|
1715
2207
|
return null;
|
|
1716
2208
|
}
|
|
1717
|
-
async function tryRegistryImport(collection, name, cwd, isWatchMode) {
|
|
2209
|
+
async function tryRegistryImport(collection, name, cwd, isWatchMode, locale) {
|
|
1718
2210
|
try {
|
|
1719
2211
|
const registryPath = join2(cwd, ".reroute", "content.ts");
|
|
1720
2212
|
const reg = await dynamicImport(registryPath, isWatchMode);
|
|
1721
2213
|
const get = reg?.getContentEntry;
|
|
1722
|
-
const entry = typeof get === "function" ? get(collection, name) : undefined;
|
|
2214
|
+
const entry = typeof get === "function" ? get(collection, name, locale) : undefined;
|
|
1723
2215
|
const moduleUrl = entry?.module;
|
|
1724
2216
|
if (!moduleUrl?.endsWith(".js"))
|
|
1725
2217
|
return null;
|
|
@@ -1745,7 +2237,7 @@ async function tryRegistryImport(collection, name, cwd, isWatchMode) {
|
|
|
1745
2237
|
async function tryChunkImport(collection, name, cwd, isWatchMode) {
|
|
1746
2238
|
try {
|
|
1747
2239
|
const chunkDir = join2(cwd, ".reroute", "chunks", collection);
|
|
1748
|
-
const files = await
|
|
2240
|
+
const files = await readdir4(chunkDir);
|
|
1749
2241
|
const matches = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
|
|
1750
2242
|
if (!matches.length)
|
|
1751
2243
|
return null;
|
|
@@ -1765,23 +2257,23 @@ async function tryChunkImport(collection, name, cwd, isWatchMode) {
|
|
|
1765
2257
|
} catch {}
|
|
1766
2258
|
return null;
|
|
1767
2259
|
}
|
|
1768
|
-
async function trySourceImport(collection, name, clientDir, isWatchMode) {
|
|
2260
|
+
async function trySourceImport(collection, name, clientDir, isWatchMode, locale) {
|
|
1769
2261
|
try {
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
if (await Bun.file(srcTsx).exists()) {
|
|
1774
|
-
absSrc = srcTsx;
|
|
1775
|
-
} else if (await Bun.file(srcTs).exists()) {
|
|
1776
|
-
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`));
|
|
1777
2265
|
}
|
|
1778
|
-
|
|
1779
|
-
|
|
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
|
+
}
|
|
1780
2271
|
}
|
|
1781
2272
|
} catch {}
|
|
1782
2273
|
return null;
|
|
1783
2274
|
}
|
|
1784
2275
|
var init_modules = __esm(() => {
|
|
2276
|
+
init_content_path();
|
|
1785
2277
|
init_imports();
|
|
1786
2278
|
});
|
|
1787
2279
|
|
|
@@ -1812,14 +2304,11 @@ function touchModule(key) {
|
|
|
1812
2304
|
}
|
|
1813
2305
|
async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
|
|
1814
2306
|
try {
|
|
1815
|
-
const
|
|
1816
|
-
|
|
1817
|
-
if (parts.length < 2) {
|
|
2307
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2308
|
+
if (!resolved) {
|
|
1818
2309
|
return;
|
|
1819
2310
|
}
|
|
1820
|
-
const
|
|
1821
|
-
const name = parts[1];
|
|
1822
|
-
const key = `${collection}:${name}`;
|
|
2311
|
+
const { key } = resolved;
|
|
1823
2312
|
const mod = await importContentModuleForPath(pathname, clientDir, cwd, isWatchMode);
|
|
1824
2313
|
if (!mod) {
|
|
1825
2314
|
return;
|
|
@@ -1839,42 +2328,25 @@ async function seedSSRModuleForPath(pathname, clientDir, cwd, isWatchMode) {
|
|
|
1839
2328
|
}
|
|
1840
2329
|
var MAX_SSR_MODULES = 200, moduleAccessOrder;
|
|
1841
2330
|
var init_seed = __esm(() => {
|
|
2331
|
+
init_content_path();
|
|
1842
2332
|
init_modules();
|
|
1843
2333
|
moduleAccessOrder = [];
|
|
1844
2334
|
});
|
|
1845
2335
|
|
|
1846
2336
|
// packages/core/src/ssr/lib/data.ts
|
|
1847
|
-
function matchPattern(pattern, pathname) {
|
|
1848
|
-
const patternParts = pattern.split("/").filter(Boolean);
|
|
1849
|
-
const pathnameParts = pathname.split("/").filter(Boolean);
|
|
1850
|
-
if (patternParts.length !== pathnameParts.length) {
|
|
1851
|
-
return null;
|
|
1852
|
-
}
|
|
1853
|
-
const params = {};
|
|
1854
|
-
for (let i = 0;i < patternParts.length; i++) {
|
|
1855
|
-
const patternPart = patternParts[i];
|
|
1856
|
-
const pathnamePart = pathnameParts[i];
|
|
1857
|
-
if (patternPart.startsWith(":")) {
|
|
1858
|
-
params[patternPart.slice(1)] = pathnamePart;
|
|
1859
|
-
} else if (patternPart !== pathnamePart) {
|
|
1860
|
-
return null;
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
return params;
|
|
1864
|
-
}
|
|
1865
2337
|
function loadContentData(pathname, searchParams) {
|
|
1866
2338
|
try {
|
|
1867
|
-
const
|
|
1868
|
-
if (
|
|
2339
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2340
|
+
if (!resolved)
|
|
1869
2341
|
return null;
|
|
1870
|
-
const key =
|
|
2342
|
+
const key = resolved.key;
|
|
1871
2343
|
const g = globalThis;
|
|
1872
2344
|
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
1873
2345
|
const dataFn = exp?.ssr?.data;
|
|
1874
2346
|
if (typeof dataFn === "function") {
|
|
1875
2347
|
const rawResult = dataFn({
|
|
1876
2348
|
pathname,
|
|
1877
|
-
params: { name:
|
|
2349
|
+
params: { name: resolved.name },
|
|
1878
2350
|
searchParams
|
|
1879
2351
|
});
|
|
1880
2352
|
const result = processDataResult(rawResult, pathname, pathname);
|
|
@@ -1896,16 +2368,7 @@ async function loadRouteDataInternal(pathname, clientDir, cwd, isWatchMode, sear
|
|
|
1896
2368
|
routes = m?.routes;
|
|
1897
2369
|
matchRouteFn = m?.matchRoute;
|
|
1898
2370
|
} else {
|
|
1899
|
-
matchRouteFn = (pathname2) =>
|
|
1900
|
-
for (const route of routes || []) {
|
|
1901
|
-
const pattern = String(route?.pattern || "");
|
|
1902
|
-
const match2 = matchPattern(pattern, pathname2);
|
|
1903
|
-
if (match2) {
|
|
1904
|
-
return { route, params: match2 };
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
return null;
|
|
1908
|
-
};
|
|
2371
|
+
matchRouteFn = (pathname2) => matchRoutes(routes || [], pathname2);
|
|
1909
2372
|
}
|
|
1910
2373
|
const pathnameOnly = pathname.split("?")[0];
|
|
1911
2374
|
const match = typeof matchRouteFn === "function" ? matchRouteFn(pathnameOnly) : null;
|
|
@@ -2046,6 +2509,7 @@ function createLazyMarker(pathname, key) {
|
|
|
2046
2509
|
};
|
|
2047
2510
|
}
|
|
2048
2511
|
var init_data = __esm(() => {
|
|
2512
|
+
init_content_path();
|
|
2049
2513
|
init_imports();
|
|
2050
2514
|
init_seed();
|
|
2051
2515
|
});
|
|
@@ -2246,18 +2710,53 @@ function replaceAppRoot(html, appHtml, appId) {
|
|
|
2246
2710
|
var init_html = () => {};
|
|
2247
2711
|
|
|
2248
2712
|
// packages/core/src/og/discovery.ts
|
|
2713
|
+
import { readdir as readdir5 } from "node:fs/promises";
|
|
2249
2714
|
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
2715
|
+
function isCatchAllRouteDirectory(name) {
|
|
2716
|
+
return CATCH_ALL_ROUTE_DIRECTORY.test(name);
|
|
2717
|
+
}
|
|
2718
|
+
async function listDynamicRouteDirectories(baseDir) {
|
|
2719
|
+
try {
|
|
2720
|
+
const entries = await readdir5(baseDir, { withFileTypes: true });
|
|
2721
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => DYNAMIC_ROUTE_DIRECTORY.test(name)).sort((a, b) => {
|
|
2722
|
+
const aIsCatchAll = isCatchAllRouteDirectory(a);
|
|
2723
|
+
const bIsCatchAll = isCatchAllRouteDirectory(b);
|
|
2724
|
+
if (aIsCatchAll !== bIsCatchAll) {
|
|
2725
|
+
return Number(aIsCatchAll) - Number(bIsCatchAll);
|
|
2726
|
+
}
|
|
2727
|
+
return a.localeCompare(b);
|
|
2728
|
+
});
|
|
2729
|
+
} catch {
|
|
2730
|
+
return [];
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
async function collectOGCandidatePaths(currentDir, parts, depth, pathsToTry, allowPartialFallback) {
|
|
2734
|
+
if (depth === parts.length) {
|
|
2735
|
+
pathsToTry.push(join2(currentDir, "[og].tsx"));
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
const literalDir = join2(currentDir, parts[depth]);
|
|
2739
|
+
try {
|
|
2740
|
+
await readdir5(literalDir);
|
|
2741
|
+
await collectOGCandidatePaths(literalDir, parts, depth + 1, pathsToTry, true);
|
|
2742
|
+
} catch {}
|
|
2743
|
+
const dynamicDirs = await listDynamicRouteDirectories(currentDir);
|
|
2744
|
+
for (const dynamicDir of dynamicDirs) {
|
|
2745
|
+
if (isCatchAllRouteDirectory(dynamicDir)) {
|
|
2746
|
+
pathsToTry.push(join2(currentDir, dynamicDir, "[og].tsx"));
|
|
2747
|
+
continue;
|
|
2748
|
+
}
|
|
2749
|
+
await collectOGCandidatePaths(join2(currentDir, dynamicDir), parts, depth + 1, pathsToTry, false);
|
|
2750
|
+
}
|
|
2751
|
+
if (allowPartialFallback) {
|
|
2752
|
+
pathsToTry.push(join2(currentDir, "[og].tsx"));
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2250
2755
|
async function findOGImageForPath(pathname, clientDir) {
|
|
2251
2756
|
const parts = pathname.split("/").filter(Boolean).filter((p) => !p.startsWith("__reroute"));
|
|
2252
2757
|
const routesDir = join2(clientDir, "routes");
|
|
2253
2758
|
const pathsToTry = [];
|
|
2254
|
-
|
|
2255
|
-
for (let i = parts.length;i > 0; i--) {
|
|
2256
|
-
const dirPath = join2(routesDir, ...parts.slice(0, i), "[og].tsx");
|
|
2257
|
-
pathsToTry.push(dirPath);
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
pathsToTry.push(join2(routesDir, "[og].tsx"));
|
|
2759
|
+
await collectOGCandidatePaths(routesDir, parts, 0, pathsToTry, true);
|
|
2261
2760
|
const uniquePaths = [...new Set(pathsToTry)];
|
|
2262
2761
|
for (const path2 of uniquePaths) {
|
|
2263
2762
|
try {
|
|
@@ -2281,28 +2780,28 @@ async function loadOGImageComponent(ogPath, isWatchMode) {
|
|
|
2281
2780
|
function extractParamsFromPath(pathname, ogPath, clientDir) {
|
|
2282
2781
|
const params = {};
|
|
2283
2782
|
const ogDir = ogPath.replace(/\/\[og\]\.tsx$/, "");
|
|
2284
|
-
const
|
|
2285
|
-
const relativePath = ogDir.replace(
|
|
2783
|
+
const routesDir = join2(clientDir, "routes");
|
|
2784
|
+
const relativePath = ogDir.replace(routesDir, "").split("/").filter(Boolean);
|
|
2286
2785
|
const pathnameParts = pathname.split("/").filter(Boolean);
|
|
2287
2786
|
for (let i = 0;i < relativePath.length && i < pathnameParts.length; i++) {
|
|
2288
2787
|
const part = relativePath[i];
|
|
2289
|
-
const
|
|
2290
|
-
if (
|
|
2291
|
-
|
|
2292
|
-
|
|
2788
|
+
const catchAllMatch = part.match(/^\[\.\.\.([^\]]+)\]$/);
|
|
2789
|
+
if (catchAllMatch) {
|
|
2790
|
+
params[catchAllMatch[1]] = pathnameParts.slice(i).join("/");
|
|
2791
|
+
break;
|
|
2293
2792
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
const match = lastRelativePart.match(/^\[([^\]]+)\]$/);
|
|
2298
|
-
if (match) {
|
|
2299
|
-
const paramName = match[1];
|
|
2300
|
-
params[paramName] = pathnameParts[relativePath.length - 1];
|
|
2793
|
+
const dynamicMatch = part.match(/^\[([^\]]+)\]$/);
|
|
2794
|
+
if (dynamicMatch) {
|
|
2795
|
+
params[dynamicMatch[1]] = pathnameParts[i];
|
|
2301
2796
|
}
|
|
2302
2797
|
}
|
|
2303
2798
|
return params;
|
|
2304
2799
|
}
|
|
2305
|
-
var
|
|
2800
|
+
var CATCH_ALL_ROUTE_DIRECTORY, DYNAMIC_ROUTE_DIRECTORY;
|
|
2801
|
+
var init_discovery2 = __esm(() => {
|
|
2802
|
+
CATCH_ALL_ROUTE_DIRECTORY = /^\[\.\.\.([^\]]+)\]$/;
|
|
2803
|
+
DYNAMIC_ROUTE_DIRECTORY = /^\[(?:\.\.\.)?[^\]]+\]$/;
|
|
2804
|
+
});
|
|
2306
2805
|
|
|
2307
2806
|
// packages/core/src/og/meta.ts
|
|
2308
2807
|
async function generateOGImageMetaTags(pathname, clientDir, ogConfig) {
|
|
@@ -2393,7 +2892,9 @@ async function extractPageMetadata(pathname, clientDir, cwd, isWatchMode, curren
|
|
|
2393
2892
|
let perPageHead = "";
|
|
2394
2893
|
let pageLang;
|
|
2395
2894
|
let statusOverride = currentStatusOverride;
|
|
2396
|
-
|
|
2895
|
+
const resolved = resolveContentPathParts(pathname);
|
|
2896
|
+
const routingPathname = resolved?.routingPathname || pathname;
|
|
2897
|
+
await extractLayoutMetadata(routingPathname, clientDir, cwd, isWatchMode, (head) => {
|
|
2397
2898
|
perPageHead += head;
|
|
2398
2899
|
}, (lang) => {
|
|
2399
2900
|
if (!pageLang)
|
|
@@ -2428,8 +2929,8 @@ ${ogMetaTags}`;
|
|
|
2428
2929
|
perPageHead += head;
|
|
2429
2930
|
}, (lang) => {
|
|
2430
2931
|
pageLang = lang;
|
|
2431
|
-
}, ogConfig, titleSuffix);
|
|
2432
|
-
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);
|
|
2433
2934
|
perPageHead += routeResult.head;
|
|
2434
2935
|
if (routeResult.lang)
|
|
2435
2936
|
pageLang = routeResult.lang;
|
|
@@ -2469,14 +2970,42 @@ async function extractLayoutMetadata(pathname, clientDir, cwd, isWatchMode, addH
|
|
|
2469
2970
|
}
|
|
2470
2971
|
} catch {}
|
|
2471
2972
|
}
|
|
2472
|
-
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) {
|
|
2473
3003
|
try {
|
|
2474
|
-
const
|
|
2475
|
-
if (
|
|
3004
|
+
const resolved = resolveContentPathParts(pathname);
|
|
3005
|
+
if (!resolved)
|
|
2476
3006
|
return;
|
|
2477
|
-
const key = `${parts[0]}:${parts[1]}`;
|
|
2478
3007
|
const g = globalThis;
|
|
2479
|
-
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
3008
|
+
const exp = g.__REROUTE_SSR_EXPORTS__?.[resolved.key];
|
|
2480
3009
|
const meta = exp?.meta;
|
|
2481
3010
|
const ssr = exp?.ssr;
|
|
2482
3011
|
addHead(buildHeadFromMeta(meta, ogConfig, titleSuffix));
|
|
@@ -2487,15 +3016,20 @@ ${ssrHead}`);
|
|
|
2487
3016
|
const lang = extractSSRLang(ssr);
|
|
2488
3017
|
if (lang)
|
|
2489
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
|
+
}
|
|
2490
3024
|
} catch {}
|
|
2491
3025
|
}
|
|
2492
3026
|
function getContentMetaFromExports(pathname) {
|
|
2493
3027
|
try {
|
|
2494
|
-
const
|
|
2495
|
-
if (
|
|
3028
|
+
const resolved = resolveContentPathParts(pathname);
|
|
3029
|
+
if (!resolved)
|
|
2496
3030
|
return;
|
|
2497
|
-
const slug =
|
|
2498
|
-
const key =
|
|
3031
|
+
const slug = resolved.name;
|
|
3032
|
+
const key = resolved.key;
|
|
2499
3033
|
const g = globalThis;
|
|
2500
3034
|
const exp = g.__REROUTE_SSR_EXPORTS__?.[key];
|
|
2501
3035
|
const meta = exp?.meta;
|
|
@@ -2509,9 +3043,10 @@ function getContentMetaFromExports(pathname) {
|
|
|
2509
3043
|
return;
|
|
2510
3044
|
}
|
|
2511
3045
|
}
|
|
2512
|
-
async function extractMatchedRouteMetadata(pathname, clientDir, m, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix) {
|
|
3046
|
+
async function extractMatchedRouteMetadata(pathname, clientDir, m, isWatchMode, statusOverride, ssrData, ogConfig, titleSuffix, routingPathname) {
|
|
2513
3047
|
const pathnameOnly = pathname.split("?")[0];
|
|
2514
|
-
const
|
|
3048
|
+
const matchPath = (routingPathname || pathname).split("?")[0];
|
|
3049
|
+
const match = typeof m.matchRoute === "function" ? m.matchRoute(matchPath) : null;
|
|
2515
3050
|
const r = match?.route;
|
|
2516
3051
|
if (!r) {
|
|
2517
3052
|
return { head: "", statusOverride: statusOverride || 404 };
|
|
@@ -2551,7 +3086,7 @@ ${ssrHead}`;
|
|
|
2551
3086
|
}
|
|
2552
3087
|
return { head: "", statusOverride };
|
|
2553
3088
|
}
|
|
2554
|
-
async function extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, currentStatusOverride, ssrData, ogConfig, titleSuffix) {
|
|
3089
|
+
async function extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, currentStatusOverride, ssrData, ogConfig, titleSuffix, routingPathname) {
|
|
2555
3090
|
let head = "";
|
|
2556
3091
|
let lang;
|
|
2557
3092
|
let statusOverride = currentStatusOverride;
|
|
@@ -2561,14 +3096,14 @@ async function extractRouteMetadata(pathname, clientDir, cwd, isWatchMode, curre
|
|
|
2561
3096
|
if (!m) {
|
|
2562
3097
|
return { head, lang, statusOverride: statusOverride || 404 };
|
|
2563
3098
|
}
|
|
2564
|
-
const
|
|
2565
|
-
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;
|
|
2566
3101
|
const r = match?.route;
|
|
2567
3102
|
if (!r) {
|
|
2568
3103
|
statusOverride = statusOverride || 404;
|
|
2569
3104
|
}
|
|
2570
3105
|
if (r && typeof r.path === "string") {
|
|
2571
|
-
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);
|
|
2572
3107
|
head = result.head;
|
|
2573
3108
|
lang = result.lang;
|
|
2574
3109
|
statusOverride = result.statusOverride;
|
|
@@ -2743,34 +3278,34 @@ function applyTitleSuffixToHead(headContent, titleSuffix) {
|
|
|
2743
3278
|
}
|
|
2744
3279
|
var init_metadata2 = __esm(() => {
|
|
2745
3280
|
init_metadata();
|
|
3281
|
+
init_pathname();
|
|
2746
3282
|
init_meta();
|
|
2747
3283
|
init_compute();
|
|
3284
|
+
init_content_path();
|
|
2748
3285
|
init_imports();
|
|
2749
3286
|
});
|
|
2750
3287
|
|
|
2751
3288
|
// packages/core/src/ssr/lib/preload.ts
|
|
2752
|
-
import { readdir as
|
|
3289
|
+
import { readdir as readdir6, stat as stat4 } from "node:fs/promises";
|
|
2753
3290
|
async function preloadContentModule(pathname, clientDir, cwd, isWatchMode) {
|
|
2754
3291
|
let extraHead = "";
|
|
2755
3292
|
let hydrationScript = "";
|
|
2756
3293
|
let statusOverride;
|
|
2757
3294
|
try {
|
|
2758
|
-
const
|
|
2759
|
-
const
|
|
2760
|
-
if (
|
|
3295
|
+
const { resolveContentPathParts: resolveContentPathParts2 } = await Promise.resolve().then(() => (init_content_path(), exports_content_path));
|
|
3296
|
+
const resolved = resolveContentPathParts2(pathname);
|
|
3297
|
+
if (!resolved) {
|
|
2761
3298
|
return { extraHead, hydrationScript };
|
|
2762
3299
|
}
|
|
2763
|
-
const collection =
|
|
2764
|
-
const name = parts[1];
|
|
3300
|
+
const { collection, name, key, locale } = resolved;
|
|
2765
3301
|
if (!await isContentCollection(clientDir, collection)) {
|
|
2766
3302
|
return { extraHead, hydrationScript };
|
|
2767
3303
|
}
|
|
2768
|
-
const modulePath = await findContentModulePath(collection, name, clientDir, cwd, isWatchMode);
|
|
3304
|
+
const modulePath = await findContentModulePath(collection, name, clientDir, cwd, isWatchMode, locale);
|
|
2769
3305
|
if (!modulePath) {
|
|
2770
3306
|
statusOverride = 404;
|
|
2771
3307
|
return { extraHead, hydrationScript, statusOverride };
|
|
2772
3308
|
}
|
|
2773
|
-
const key = `${collection}:${name}`;
|
|
2774
3309
|
extraHead += `
|
|
2775
3310
|
<link rel="modulepreload" href="${modulePath}" />`;
|
|
2776
3311
|
hydrationScript += `<script>
|
|
@@ -2812,12 +3347,12 @@ async function findLatestCandidate(chunkDir, candidates) {
|
|
|
2812
3347
|
}
|
|
2813
3348
|
return latest;
|
|
2814
3349
|
}
|
|
2815
|
-
async function findContentModulePath(collection, name, clientDir, cwd, isWatchMode) {
|
|
3350
|
+
async function findContentModulePath(collection, name, clientDir, cwd, isWatchMode, locale) {
|
|
2816
3351
|
try {
|
|
2817
3352
|
const registryPath = join2(cwd, ".reroute", "content.ts");
|
|
2818
3353
|
const reg = await dynamicImport(registryPath, isWatchMode);
|
|
2819
3354
|
const get = reg?.getContentEntry;
|
|
2820
|
-
const entry = typeof get === "function" ? get(collection, name) : undefined;
|
|
3355
|
+
const entry = typeof get === "function" ? get(collection, name, locale) : undefined;
|
|
2821
3356
|
const moduleUrl = entry?.module;
|
|
2822
3357
|
if (moduleUrl?.endsWith(".js")) {
|
|
2823
3358
|
return moduleUrl;
|
|
@@ -2825,7 +3360,7 @@ async function findContentModulePath(collection, name, clientDir, cwd, isWatchMo
|
|
|
2825
3360
|
} catch {}
|
|
2826
3361
|
try {
|
|
2827
3362
|
const chunkDir = join2(cwd, ".reroute", "chunks", collection);
|
|
2828
|
-
const files = await
|
|
3363
|
+
const files = await readdir6(chunkDir);
|
|
2829
3364
|
const candidates = files.filter((n) => n.startsWith(`${name}.`) && n.endsWith(".js"));
|
|
2830
3365
|
if (candidates.length) {
|
|
2831
3366
|
const latest = await findLatestCandidate(chunkDir, candidates);
|
|
@@ -2833,13 +3368,18 @@ async function findContentModulePath(collection, name, clientDir, cwd, isWatchMo
|
|
|
2833
3368
|
}
|
|
2834
3369
|
} catch {}
|
|
2835
3370
|
try {
|
|
2836
|
-
const
|
|
2837
|
-
const
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
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
|
+
}
|
|
2843
3383
|
}
|
|
2844
3384
|
} catch {}
|
|
2845
3385
|
return null;
|
|
@@ -3033,11 +3573,18 @@ function duplicateQueryParamData(ssrData) {
|
|
|
3033
3573
|
return duplicated;
|
|
3034
3574
|
}
|
|
3035
3575
|
function getContentKeyFromPathname(pathname) {
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
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
|
+
}
|
|
3041
3588
|
}
|
|
3042
3589
|
function createContentCaptureScript() {
|
|
3043
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>`;
|
|
@@ -3113,13 +3660,14 @@ function createSSRPathnameScript(pathname) {
|
|
|
3113
3660
|
return "";
|
|
3114
3661
|
}
|
|
3115
3662
|
}
|
|
3116
|
-
function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig, traceContext, titleSuffix) {
|
|
3663
|
+
function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig, traceContext, titleSuffix, i18n) {
|
|
3117
3664
|
let script = "";
|
|
3118
3665
|
script += createContentCaptureScript();
|
|
3119
3666
|
script += createSSRPathnameScript(pathname);
|
|
3120
3667
|
if (pathname) {
|
|
3121
3668
|
script += createSSRExportsScript(pathname);
|
|
3122
3669
|
}
|
|
3670
|
+
script += createI18nScript(i18n);
|
|
3123
3671
|
script += createTelemetryConfigScript(browserTelemetryConfig);
|
|
3124
3672
|
script += createTraceContextScript(traceContext);
|
|
3125
3673
|
script += createTitleSuffixScript(titleSuffix);
|
|
@@ -3139,7 +3687,9 @@ function createDataScript(ssrData, errorMsg, pathname, browserTelemetryConfig, t
|
|
|
3139
3687
|
}
|
|
3140
3688
|
return script;
|
|
3141
3689
|
}
|
|
3142
|
-
var init_data2 = () => {
|
|
3690
|
+
var init_data2 = __esm(() => {
|
|
3691
|
+
init_content_path();
|
|
3692
|
+
});
|
|
3143
3693
|
|
|
3144
3694
|
// packages/core/src/ssr/lib/scripts/feeds.ts
|
|
3145
3695
|
function createFeedsScript() {
|
|
@@ -3367,10 +3917,10 @@ function generateCollectionScripts(byCollectionForSSR) {
|
|
|
3367
3917
|
} catch {}
|
|
3368
3918
|
return "";
|
|
3369
3919
|
}
|
|
3370
|
-
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) {
|
|
3371
3921
|
let scripts = preloadScript;
|
|
3372
3922
|
scripts += collectionScripts;
|
|
3373
|
-
scripts += createDataScript(ssrData, isWatchMode ? ssrError : undefined, pathname, browserTelemetryConfig, traceContext, titleSuffix);
|
|
3923
|
+
scripts += createDataScript(ssrData, isWatchMode ? ssrError : undefined, pathname, browserTelemetryConfig, traceContext, titleSuffix, i18n);
|
|
3374
3924
|
scripts += createFeedsScript();
|
|
3375
3925
|
scripts += createLlmsScript();
|
|
3376
3926
|
if (bundleUrl) {
|
|
@@ -3533,7 +4083,7 @@ async function renderSSRDocument(options) {
|
|
|
3533
4083
|
const browserTelemetryConfig = serializeBrowserTelemetryConfig2(browserTelemetryConfigRaw);
|
|
3534
4084
|
const traceContext = getTraceContextForInjection(options.parentSpan);
|
|
3535
4085
|
const hydrationScript = await withSpan("ssr.generate.scripts", async (span) => {
|
|
3536
|
-
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);
|
|
3537
4087
|
span.setAttribute("reroute.scripts.size", script.length);
|
|
3538
4088
|
return script;
|
|
3539
4089
|
});
|
|
@@ -3551,12 +4101,13 @@ async function renderSSRDocument(options) {
|
|
|
3551
4101
|
dedent(setup2.metadataResult.perPageHead)
|
|
3552
4102
|
].filter(Boolean).join(`
|
|
3553
4103
|
`));
|
|
4104
|
+
const i18nLocale = options.i18n?.enabled ? String(options.i18n.locale || "") : "";
|
|
3554
4105
|
const html2 = withSpanSync("ssr.apply.template", (span) => {
|
|
3555
4106
|
const result = applyIndexTemplate(baseTemplate, appHtml, {
|
|
3556
4107
|
head: [setup2.inlineStyleTag, combinedHead].filter(Boolean).join(`
|
|
3557
4108
|
`),
|
|
3558
4109
|
hydrationScript,
|
|
3559
|
-
lang: setup2.metadataResult.pageLang || lang,
|
|
4110
|
+
lang: setup2.metadataResult.pageLang || i18nLocale || lang,
|
|
3560
4111
|
appId
|
|
3561
4112
|
});
|
|
3562
4113
|
span.setAttributes({
|
|
@@ -4734,6 +5285,55 @@ async function discoverRoutes(cwd, isWatchMode) {
|
|
|
4734
5285
|
}
|
|
4735
5286
|
return { staticRoutes, dynamicRoutes };
|
|
4736
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
|
+
}
|
|
4737
5337
|
async function discoverCollectionContent(cwd, collection, isWatchMode, baseUrl) {
|
|
4738
5338
|
const entries = [];
|
|
4739
5339
|
try {
|
|
@@ -4745,18 +5345,26 @@ async function discoverCollectionContent(cwd, collection, isWatchMode, baseUrl)
|
|
|
4745
5345
|
const url = `${Bun.pathToFileURL(collectionFile).href}${isWatchMode ? `?t=${Date.now()}` : ""}`;
|
|
4746
5346
|
const mod = await import(url);
|
|
4747
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
|
+
}
|
|
4748
5355
|
for (const item of items) {
|
|
5356
|
+
if (item.name)
|
|
5357
|
+
continue;
|
|
4749
5358
|
const href = String(item.href || "");
|
|
5359
|
+
if (!href)
|
|
5360
|
+
continue;
|
|
4750
5361
|
const meta = item.meta || {};
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
};
|
|
4758
|
-
entries.push(entry);
|
|
4759
|
-
}
|
|
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
|
+
});
|
|
4760
5368
|
}
|
|
4761
5369
|
} catch (error) {
|
|
4762
5370
|
console.error(`[reroute] Failed to discover collection ${collection}:`, error);
|
|
@@ -5051,11 +5659,17 @@ async function discoverCollectionFeedItems(cwd, collection, isWatchMode, baseUrl
|
|
|
5051
5659
|
const url = `${Bun.pathToFileURL(collectionFile).href}${isWatchMode ? `?t=${Date.now()}` : ""}`;
|
|
5052
5660
|
const mod = await import(url);
|
|
5053
5661
|
const contentItems = mod.items || [];
|
|
5662
|
+
const defaultLocale = mod.defaultLocale || "en-US";
|
|
5663
|
+
const { localizeContentHref: localizeContentHref2 } = await Promise.resolve().then(() => (init_pathname(), exports_pathname));
|
|
5054
5664
|
for (const item of contentItems) {
|
|
5055
|
-
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 || "");
|
|
5056
5668
|
const meta = item.meta || {};
|
|
5057
5669
|
if (href) {
|
|
5058
|
-
|
|
5670
|
+
const rssItem = createRSSItemFromMetaAndHref(href, meta, baseUrl, item, rssConfig);
|
|
5671
|
+
rssItem.locale = locale;
|
|
5672
|
+
items.push(rssItem);
|
|
5059
5673
|
}
|
|
5060
5674
|
}
|
|
5061
5675
|
} catch (error) {
|
|
@@ -5321,7 +5935,7 @@ function generateRSSXML(feed, options = {}) {
|
|
|
5321
5935
|
<link>${escapeXml(feed.link)}</link>
|
|
5322
5936
|
<description>${escapeXml(feed.description)}</description>
|
|
5323
5937
|
<lastBuildDate>${lastBuildDate}</lastBuildDate>
|
|
5324
|
-
<language
|
|
5938
|
+
<language>${escapeXml(feed.language || "en")}</language>
|
|
5325
5939
|
<atom:link href="${escapeXml(feed.link)}" rel="self" type="application/rss+xml" />
|
|
5326
5940
|
${itemsXML}
|
|
5327
5941
|
</channel>
|
|
@@ -5483,6 +6097,7 @@ async function generateSitemap(discovery4, baseUrl, options = {}) {
|
|
|
5483
6097
|
return createSingleSitemap(allEntries);
|
|
5484
6098
|
}
|
|
5485
6099
|
function generateSitemapXML(entries) {
|
|
6100
|
+
const hasAlternates = entries.some((e) => e.alternates && e.alternates.length > 0);
|
|
5486
6101
|
const urlsetEntries = entries.map((entry) => {
|
|
5487
6102
|
let xml = ` <url>
|
|
5488
6103
|
<loc>${escapeXml2(entry.loc)}</loc>`;
|
|
@@ -5498,13 +6113,20 @@ function generateSitemapXML(entries) {
|
|
|
5498
6113
|
xml += `
|
|
5499
6114
|
<priority>${entry.priority.toFixed(1)}</priority>`;
|
|
5500
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
|
+
}
|
|
5501
6122
|
xml += `
|
|
5502
6123
|
</url>`;
|
|
5503
6124
|
return xml;
|
|
5504
6125
|
}).join(`
|
|
5505
6126
|
`);
|
|
6127
|
+
const xhtmlNs = hasAlternates ? ' xmlns:xhtml="http://www.w3.org/1999/xhtml"' : "";
|
|
5506
6128
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
5507
|
-
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
6129
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"${xhtmlNs}>
|
|
5508
6130
|
${urlsetEntries}
|
|
5509
6131
|
</urlset>`;
|
|
5510
6132
|
}
|
|
@@ -5602,7 +6224,8 @@ async function renderSSRDocumentStream(options) {
|
|
|
5602
6224
|
...parts
|
|
5603
6225
|
};
|
|
5604
6226
|
});
|
|
5605
|
-
const
|
|
6227
|
+
const i18nLocale = options.i18n?.enabled ? String(options.i18n.locale || "") : "";
|
|
6228
|
+
const pageLang = setup2.metadataResult.pageLang || i18nLocale || lang;
|
|
5606
6229
|
let headWithLang = htmlHead.replace(/<html([^>]*)>/i, (_m, attrs) => {
|
|
5607
6230
|
const hasLang = /(^|\s)lang\s*=/.test(attrs);
|
|
5608
6231
|
const newAttrs = hasLang ? attrs.replace(/lang\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/i, `lang="${pageLang}"`) : `${attrs} lang="${pageLang}"`;
|
|
@@ -5645,7 +6268,8 @@ async function renderSSRDocumentStream(options) {
|
|
|
5645
6268
|
parentSpan: options.parentSpan,
|
|
5646
6269
|
timeout: options.timeout,
|
|
5647
6270
|
ssrExport: setup2.metadataResult.ssrExport,
|
|
5648
|
-
titleSuffix: options.titleSuffix
|
|
6271
|
+
titleSuffix: options.titleSuffix,
|
|
6272
|
+
i18n: options.i18n
|
|
5649
6273
|
});
|
|
5650
6274
|
if (debug)
|
|
5651
6275
|
console.log(`[renderStream] ${pathname} - returning stream: ${(performance.now() - t0).toFixed(2)}ms`);
|
|
@@ -5758,7 +6382,7 @@ function buildStreamingScripts(ctx) {
|
|
|
5758
6382
|
ssrDataSnapshot[key] = value;
|
|
5759
6383
|
}
|
|
5760
6384
|
}
|
|
5761
|
-
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);
|
|
5762
6386
|
const feedsScript = createFeedsScript();
|
|
5763
6387
|
const llmsScript = createLlmsScript();
|
|
5764
6388
|
let allScripts = dataScript + feedsScript + llmsScript + collectionScripts + ctx.preloadHydrationScript;
|
|
@@ -5890,6 +6514,7 @@ var init_src = __esm(() => {
|
|
|
5890
6514
|
init_bundler();
|
|
5891
6515
|
init_config();
|
|
5892
6516
|
init_content();
|
|
6517
|
+
init_i18n();
|
|
5893
6518
|
init_llms();
|
|
5894
6519
|
init_og();
|
|
5895
6520
|
init_robots();
|
|
@@ -5902,6 +6527,7 @@ var init_src = __esm(() => {
|
|
|
5902
6527
|
var exports_core = {};
|
|
5903
6528
|
__export(exports_core, {
|
|
5904
6529
|
toPromise: () => toPromise,
|
|
6530
|
+
toOgLocale: () => toOgLocale,
|
|
5905
6531
|
toBytes: () => toBytes,
|
|
5906
6532
|
stripStart: () => stripStart,
|
|
5907
6533
|
stripHtmlTags: () => stripHtmlTags,
|
|
@@ -5913,6 +6539,7 @@ __export(exports_core, {
|
|
|
5913
6539
|
setGlobalSSRData: () => setGlobalSSRData,
|
|
5914
6540
|
setGlobalCollections: () => setGlobalCollections,
|
|
5915
6541
|
seedSSRModuleForPath: () => seedSSRModuleForPath,
|
|
6542
|
+
resolveLocale: () => resolveLocale,
|
|
5916
6543
|
resetSSRAccessTracking: () => resetSSRAccessTracking,
|
|
5917
6544
|
renderSSRDocumentStream: () => renderSSRDocumentStream,
|
|
5918
6545
|
renderSSRDocument: () => renderSSRDocument,
|
|
@@ -5921,7 +6548,17 @@ __export(exports_core, {
|
|
|
5921
6548
|
processCollections: () => processCollections,
|
|
5922
6549
|
preloadContentModule: () => preloadContentModule,
|
|
5923
6550
|
performSSRSetup: () => performSSRSetup,
|
|
6551
|
+
parseCookieValue: () => parseCookieValue,
|
|
6552
|
+
parseContentPath: () => parseContentPath,
|
|
6553
|
+
normalizePathname: () => normalizePathname,
|
|
6554
|
+
negotiateLocale: () => negotiateLocale,
|
|
5924
6555
|
mergeLayoutData: () => mergeLayoutData,
|
|
6556
|
+
matchRoutes: () => matchRoutes,
|
|
6557
|
+
matchRoutePattern: () => matchRoutePattern,
|
|
6558
|
+
lookupMessage: () => lookupMessage,
|
|
6559
|
+
looksLikeLocale: () => looksLikeLocale,
|
|
6560
|
+
localizeHref: () => localizeHref,
|
|
6561
|
+
localizeContentHref: () => localizeContentHref,
|
|
5925
6562
|
loadRoutesModule: () => loadRoutesModule,
|
|
5926
6563
|
loadOGImageComponent: () => loadOGImageComponent,
|
|
5927
6564
|
loadIndexHtml: () => loadIndexHtml,
|
|
@@ -5934,11 +6571,13 @@ __export(exports_core, {
|
|
|
5934
6571
|
inlineTailwindCSS: () => inlineTailwindCSS,
|
|
5935
6572
|
importContentModuleForPath: () => importContentModuleForPath,
|
|
5936
6573
|
htmlToMarkdown: () => htmlToMarkdown,
|
|
6574
|
+
hreflangTags: () => hreflangTags,
|
|
5937
6575
|
gzipIfAccepted: () => gzipIfAccepted,
|
|
5938
6576
|
getSitemapExcludedRoutes: () => getSitemapExcludedRoutes,
|
|
5939
6577
|
getRedirectSourcePaths: () => getRedirectSourcePaths,
|
|
5940
6578
|
getPatternDepth: () => getPatternDepth,
|
|
5941
6579
|
getMimeType: () => getMimeType,
|
|
6580
|
+
getMessage: () => getMessage,
|
|
5942
6581
|
getMatchingLayouts: () => getMatchingLayouts,
|
|
5943
6582
|
getContentMeta: () => getContentMeta,
|
|
5944
6583
|
generateSitemapXML: () => generateSitemapXML,
|
|
@@ -5955,6 +6594,7 @@ __export(exports_core, {
|
|
|
5955
6594
|
generateContentHash: () => generateContentHash,
|
|
5956
6595
|
generateCollectionScripts: () => generateCollectionScripts,
|
|
5957
6596
|
generateAtomXML: () => generateAtomXML,
|
|
6597
|
+
formatMessage: () => formatMessage,
|
|
5958
6598
|
formatAsText: () => formatAsText,
|
|
5959
6599
|
formatAsMarkdown: () => formatAsMarkdown,
|
|
5960
6600
|
findOGImageForPath: () => findOGImageForPath,
|
|
@@ -5974,10 +6614,12 @@ __export(exports_core, {
|
|
|
5974
6614
|
discoverRoutes: () => discoverRoutes,
|
|
5975
6615
|
discoverRobotsData: () => discoverRobotsData,
|
|
5976
6616
|
discoverRSSData: () => discoverRSSData,
|
|
6617
|
+
discoverI18n: () => discoverI18n,
|
|
5977
6618
|
discoverCollections: () => discoverCollections,
|
|
5978
6619
|
discoverCollectionContent: () => discoverCollectionContent,
|
|
5979
6620
|
defineConfig: () => defineConfig,
|
|
5980
6621
|
deduplicateMetaTags: () => deduplicateMetaTags,
|
|
6622
|
+
createTranslator: () => createTranslator,
|
|
5981
6623
|
createLlmsScript: () => createLlmsScript,
|
|
5982
6624
|
createLayoutDataKey: () => createLayoutDataKey,
|
|
5983
6625
|
createLayoutCacheKey: () => createLayoutCacheKey,
|
|
@@ -5985,13 +6627,17 @@ __export(exports_core, {
|
|
|
5985
6627
|
createDataScript: () => createDataScript,
|
|
5986
6628
|
createCollectionScript: () => createCollectionScript,
|
|
5987
6629
|
createBundlePreload: () => createBundlePreload,
|
|
6630
|
+
contentNegotiateRedirect: () => contentNegotiateRedirect,
|
|
6631
|
+
contentKey: () => contentKey,
|
|
5988
6632
|
computeSSRDataForPath: () => computeSSRDataForPath,
|
|
5989
6633
|
computeSSRData: () => computeSSRData,
|
|
5990
6634
|
computeRouteData: () => computeRouteData,
|
|
5991
6635
|
computeLayoutData: () => computeLayoutData,
|
|
5992
6636
|
computeContentData: () => computeContentData,
|
|
5993
6637
|
compressStreamIfAccepted: () => compressStreamIfAccepted,
|
|
6638
|
+
compareRouteSpecificity: () => compareRouteSpecificity,
|
|
5994
6639
|
cleanupPathScopedSSRData: () => cleanupPathScopedSSRData,
|
|
6640
|
+
buildLocaleCookie: () => buildLocaleCookie,
|
|
5995
6641
|
buildHeadFromMeta: () => buildHeadFromMeta,
|
|
5996
6642
|
blockSearchCrawlers: () => blockSearchCrawlers,
|
|
5997
6643
|
blockAITrainingCrawlers: () => blockAITrainingCrawlers,
|
|
@@ -6007,6 +6653,9 @@ __export(exports_core, {
|
|
|
6007
6653
|
SEARCH_CRAWLERS: () => SEARCH_CRAWLERS,
|
|
6008
6654
|
LRUCache: () => LRUCache,
|
|
6009
6655
|
DefaultOGTemplate: () => DefaultOGTemplate,
|
|
6656
|
+
DEFAULT_LOCALES_DIR: () => DEFAULT_LOCALES_DIR,
|
|
6657
|
+
DEFAULT_LOCALE: () => DEFAULT_LOCALE,
|
|
6658
|
+
DEFAULT_COOKIE: () => DEFAULT_COOKIE,
|
|
6010
6659
|
AI_CRAWLERS: () => AI_CRAWLERS
|
|
6011
6660
|
});
|
|
6012
6661
|
var init_core = __esm(() => {
|
|
@@ -6031,7 +6680,7 @@ function getNamingConfig(options) {
|
|
|
6031
6680
|
|
|
6032
6681
|
// packages/cli/src/commands/lib/env.ts
|
|
6033
6682
|
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
6034
|
-
import { join as
|
|
6683
|
+
import { join as join4 } from "node:path";
|
|
6035
6684
|
function parseEnvFile(content2) {
|
|
6036
6685
|
const env = {};
|
|
6037
6686
|
const lines = content2.split(`
|
|
@@ -6057,7 +6706,7 @@ function loadEnvFiles(cwd, mode = "development") {
|
|
|
6057
6706
|
const env = {};
|
|
6058
6707
|
const loadedFiles = [];
|
|
6059
6708
|
for (const file of envFiles) {
|
|
6060
|
-
const filePath =
|
|
6709
|
+
const filePath = join4(cwd, file);
|
|
6061
6710
|
if (existsSync2(filePath)) {
|
|
6062
6711
|
try {
|
|
6063
6712
|
const content2 = readFileSync(filePath, "utf-8");
|
|
@@ -6101,11 +6750,11 @@ var init_env = () => {};
|
|
|
6101
6750
|
|
|
6102
6751
|
// packages/cli/src/commands/lib/markdown/availability.ts
|
|
6103
6752
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
6104
|
-
import { dirname, join as
|
|
6753
|
+
import { dirname, join as join5 } from "node:path";
|
|
6105
6754
|
function isPackageAvailable(cwd, packageName) {
|
|
6106
6755
|
let currentDir = cwd;
|
|
6107
6756
|
for (let i = 0;i < 5; i++) {
|
|
6108
|
-
const packageJsonPath =
|
|
6757
|
+
const packageJsonPath = join5(currentDir, "package.json");
|
|
6109
6758
|
if (existsSync3(packageJsonPath)) {
|
|
6110
6759
|
try {
|
|
6111
6760
|
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
@@ -6177,7 +6826,7 @@ var init_availability = () => {};
|
|
|
6177
6826
|
|
|
6178
6827
|
// packages/cli/src/commands/lib/markdown/processor.ts
|
|
6179
6828
|
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
|
|
6180
|
-
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";
|
|
6181
6830
|
import matter from "gray-matter";
|
|
6182
6831
|
function convertPropertiesToJsx(properties) {
|
|
6183
6832
|
const newProperties = {};
|
|
@@ -6236,7 +6885,7 @@ function processMarkdownFile(filePath) {
|
|
|
6236
6885
|
function isMdxAvailable2(cwd) {
|
|
6237
6886
|
let currentDir = cwd;
|
|
6238
6887
|
for (let i = 0;i < 5; i++) {
|
|
6239
|
-
const packageJsonPath =
|
|
6888
|
+
const packageJsonPath = join6(currentDir, "package.json");
|
|
6240
6889
|
if (existsSync4(packageJsonPath)) {
|
|
6241
6890
|
try {
|
|
6242
6891
|
const packageJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
@@ -6260,10 +6909,10 @@ function isMdxAvailable2(cwd) {
|
|
|
6260
6909
|
}
|
|
6261
6910
|
function tryLoadModule(cwd, moduleName) {
|
|
6262
6911
|
const pathsToTry = [
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6912
|
+
join6(cwd, `node_modules/${moduleName}`),
|
|
6913
|
+
join6(cwd, `../node_modules/${moduleName}`),
|
|
6914
|
+
join6(cwd, `../../node_modules/${moduleName}`),
|
|
6915
|
+
join6(cwd, `../../../node_modules/${moduleName}`)
|
|
6267
6916
|
];
|
|
6268
6917
|
for (const modulePath of pathsToTry) {
|
|
6269
6918
|
try {
|
|
@@ -6593,7 +7242,7 @@ function isProductionMode(args = []) {
|
|
|
6593
7242
|
}
|
|
6594
7243
|
|
|
6595
7244
|
// packages/cli/src/commands/lib/streaming/analyzer.ts
|
|
6596
|
-
import { dirname as dirname3, join as
|
|
7245
|
+
import { dirname as dirname3, join as join7 } from "node:path";
|
|
6597
7246
|
function hasSSRDataExport(source) {
|
|
6598
7247
|
if (SSR_DATA_INLINE_EXPORT_REGEX.test(source)) {
|
|
6599
7248
|
return true;
|
|
@@ -6621,10 +7270,10 @@ async function analyzeRouteForStreaming(options) {
|
|
|
6621
7270
|
}
|
|
6622
7271
|
async function findSkeletonForTarget(routesDir, relativePath, type) {
|
|
6623
7272
|
const dirName = normalizeRelativePath(dirname3(relativePath));
|
|
6624
|
-
const baseDir = dirName === "." ? routesDir :
|
|
7273
|
+
const baseDir = dirName === "." ? routesDir : join7(routesDir, dirName).replace(/\\/g, "/");
|
|
6625
7274
|
const candidates = type === "layout" ? ["[layout+skeleton].tsx", "[layout+skeleton].ts"] : ["[skeleton].tsx", "[skeleton].ts"];
|
|
6626
7275
|
for (const candidate of candidates) {
|
|
6627
|
-
const candidatePath =
|
|
7276
|
+
const candidatePath = join7(baseDir, candidate);
|
|
6628
7277
|
try {
|
|
6629
7278
|
const file = Bun.file(candidatePath);
|
|
6630
7279
|
if (await file.exists()) {
|
|
@@ -6645,12 +7294,12 @@ var init_analyzer = __esm(() => {
|
|
|
6645
7294
|
});
|
|
6646
7295
|
|
|
6647
7296
|
// packages/cli/src/commands/lib/streaming/suspense.ts
|
|
6648
|
-
import { dirname as dirname4, join as
|
|
7297
|
+
import { dirname as dirname4, join as join8, relative as relative2 } from "node:path";
|
|
6649
7298
|
async function generateStreamingWrapper(options) {
|
|
6650
7299
|
const { cwd, relativeFilePath, analysis, config: config2 } = options;
|
|
6651
|
-
const streamingModulePath =
|
|
7300
|
+
const streamingModulePath = join8(cwd, ".reroute", "streaming", relativeFilePath).replace(/\.(tsx|ts)$/, ".tsx");
|
|
6652
7301
|
const wrapperDir = dirname4(streamingModulePath);
|
|
6653
|
-
const originalModuleWithoutExt = removeExtension(
|
|
7302
|
+
const originalModuleWithoutExt = removeExtension(join8(cwd, "src", "client", "routes", relativeFilePath));
|
|
6654
7303
|
const originalImportPath = toImportPath(wrapperDir, originalModuleWithoutExt);
|
|
6655
7304
|
const skeletonImportBlock = await resolveSkeletonBlock({
|
|
6656
7305
|
analysis,
|
|
@@ -6692,7 +7341,7 @@ async function resolveSkeletonBlock(args) {
|
|
|
6692
7341
|
}
|
|
6693
7342
|
function resolveConfiguredSkeletonPath(value, cwd) {
|
|
6694
7343
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
6695
|
-
return value.startsWith("/") ? value :
|
|
7344
|
+
return value.startsWith("/") ? value : join8(cwd, value);
|
|
6696
7345
|
}
|
|
6697
7346
|
if (value && !warnedSkeletonType) {
|
|
6698
7347
|
console.warn("[reroute/streaming] default skeletons must be provided as string module paths in reroute.config.ts");
|
|
@@ -6729,13 +7378,13 @@ var init_suspense = () => {};
|
|
|
6729
7378
|
// packages/cli/src/commands/lib/tailwind.ts
|
|
6730
7379
|
import { spawn } from "node:child_process";
|
|
6731
7380
|
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
6732
|
-
import { join as
|
|
7381
|
+
import { join as join9 } from "node:path";
|
|
6733
7382
|
function isTailwindAvailable(cwd) {
|
|
6734
7383
|
const pathsToTry = [
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
7384
|
+
join9(cwd, "package.json"),
|
|
7385
|
+
join9(cwd, "../package.json"),
|
|
7386
|
+
join9(cwd, "../../package.json"),
|
|
7387
|
+
join9(cwd, "../../../package.json")
|
|
6739
7388
|
];
|
|
6740
7389
|
for (const packageJsonPath of pathsToTry) {
|
|
6741
7390
|
if (!existsSync5(packageJsonPath)) {
|
|
@@ -6756,8 +7405,8 @@ function isTailwindAvailable(cwd) {
|
|
|
6756
7405
|
return false;
|
|
6757
7406
|
}
|
|
6758
7407
|
function getTailwindPaths(cwd) {
|
|
6759
|
-
const input =
|
|
6760
|
-
const output =
|
|
7408
|
+
const input = join9(cwd, "src/client/theme.css");
|
|
7409
|
+
const output = join9(cwd, ".reroute/theme.css");
|
|
6761
7410
|
return { input, output };
|
|
6762
7411
|
}
|
|
6763
7412
|
function hasTailwindInput(cwd) {
|
|
@@ -6774,10 +7423,10 @@ function hasTailwindInput(cwd) {
|
|
|
6774
7423
|
}
|
|
6775
7424
|
function resolveTailwindBin(cwd) {
|
|
6776
7425
|
const pathsToTry = [
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
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")
|
|
6781
7430
|
];
|
|
6782
7431
|
for (const binPath of pathsToTry) {
|
|
6783
7432
|
if (existsSync5(binPath)) {
|
|
@@ -6848,12 +7497,12 @@ __export(exports_gen, {
|
|
|
6848
7497
|
default: () => gen
|
|
6849
7498
|
});
|
|
6850
7499
|
import { watch } from "node:fs";
|
|
6851
|
-
import { mkdir as mkdir2, readdir as
|
|
6852
|
-
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";
|
|
6853
7502
|
import { pathToFileURL as pathToFileURL8 } from "node:url";
|
|
6854
7503
|
async function bundleThemeCssIntoArtifacts(cwd) {
|
|
6855
|
-
const themeCssPath =
|
|
6856
|
-
const artifactsPath =
|
|
7504
|
+
const themeCssPath = join10(cwd, ".reroute", "theme.css");
|
|
7505
|
+
const artifactsPath = join10(cwd, OUTPUT_ARTIFACTS);
|
|
6857
7506
|
try {
|
|
6858
7507
|
const cssContent = await Bun.file(themeCssPath).text();
|
|
6859
7508
|
if (!cssContent)
|
|
@@ -6879,11 +7528,11 @@ async function bundleThemeCssIntoArtifacts(cwd) {
|
|
|
6879
7528
|
async function ensureOutputDir(cwd, options = {}) {
|
|
6880
7529
|
const { clean = true } = options;
|
|
6881
7530
|
try {
|
|
6882
|
-
const outputPath =
|
|
7531
|
+
const outputPath = join10(cwd, OUTPUT_DIR);
|
|
6883
7532
|
if (clean) {
|
|
6884
7533
|
let needsCleanup = false;
|
|
6885
7534
|
try {
|
|
6886
|
-
const entries = await
|
|
7535
|
+
const entries = await readdir7(outputPath);
|
|
6887
7536
|
needsCleanup = entries.length > 0;
|
|
6888
7537
|
} catch {}
|
|
6889
7538
|
if (needsCleanup) {
|
|
@@ -6892,9 +7541,9 @@ async function ensureOutputDir(cwd, options = {}) {
|
|
|
6892
7541
|
}
|
|
6893
7542
|
}
|
|
6894
7543
|
await mkdir2(outputPath, { recursive: true });
|
|
6895
|
-
await mkdir2(
|
|
6896
|
-
await mkdir2(
|
|
6897
|
-
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 });
|
|
6898
7547
|
} catch {}
|
|
6899
7548
|
}
|
|
6900
7549
|
async function writeStubFiles(cwd) {
|
|
@@ -6952,11 +7601,11 @@ import './artifacts';
|
|
|
6952
7601
|
import './routes'; // Import routes (bundles all route components)
|
|
6953
7602
|
import '../src/index';
|
|
6954
7603
|
`;
|
|
6955
|
-
await Bun.write(
|
|
6956
|
-
await Bun.write(
|
|
6957
|
-
await Bun.write(
|
|
6958
|
-
await Bun.write(
|
|
6959
|
-
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);
|
|
6960
7609
|
console.log("[reroute/gen] Initialized stub files");
|
|
6961
7610
|
}
|
|
6962
7611
|
function shouldSkipFile(relativePath, entryName) {
|
|
@@ -6976,10 +7625,10 @@ function shouldSkipFile(relativePath, entryName) {
|
|
|
6976
7625
|
}
|
|
6977
7626
|
async function scanDirectory(dir, base = "") {
|
|
6978
7627
|
const files = [];
|
|
6979
|
-
const entries = await
|
|
7628
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
6980
7629
|
for (const entry of entries) {
|
|
6981
|
-
const fullPath =
|
|
6982
|
-
const relativePath =
|
|
7630
|
+
const fullPath = join10(dir, entry.name);
|
|
7631
|
+
const relativePath = join10(base, entry.name);
|
|
6983
7632
|
if (entry.isDirectory()) {
|
|
6984
7633
|
if (entry.name === "content")
|
|
6985
7634
|
continue;
|
|
@@ -6995,10 +7644,10 @@ async function scanDirectory(dir, base = "") {
|
|
|
6995
7644
|
}
|
|
6996
7645
|
async function scan404Files(dir, base = "") {
|
|
6997
7646
|
const files = [];
|
|
6998
|
-
const entries = await
|
|
7647
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
6999
7648
|
for (const entry of entries) {
|
|
7000
|
-
const fullPath =
|
|
7001
|
-
const relativePath =
|
|
7649
|
+
const fullPath = join10(dir, entry.name);
|
|
7650
|
+
const relativePath = join10(base, entry.name);
|
|
7002
7651
|
if (entry.isDirectory()) {
|
|
7003
7652
|
const nested = await scan404Files(fullPath, relativePath);
|
|
7004
7653
|
files.push(...nested);
|
|
@@ -7011,10 +7660,10 @@ async function scan404Files(dir, base = "") {
|
|
|
7011
7660
|
}
|
|
7012
7661
|
async function scanOgFiles(dir, base = "") {
|
|
7013
7662
|
const files = [];
|
|
7014
|
-
const entries = await
|
|
7663
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
7015
7664
|
for (const entry of entries) {
|
|
7016
|
-
const fullPath =
|
|
7017
|
-
const relativePath =
|
|
7665
|
+
const fullPath = join10(dir, entry.name);
|
|
7666
|
+
const relativePath = join10(base, entry.name);
|
|
7018
7667
|
if (entry.isDirectory()) {
|
|
7019
7668
|
if (entry.name === "content")
|
|
7020
7669
|
continue;
|
|
@@ -7068,17 +7717,7 @@ function fileToRoute(filePath) {
|
|
|
7068
7717
|
};
|
|
7069
7718
|
}
|
|
7070
7719
|
function sortRoutes(routes) {
|
|
7071
|
-
return routes.sort((a, b) =>
|
|
7072
|
-
const aDepth = a.pattern.split("/").length;
|
|
7073
|
-
const bDepth = b.pattern.split("/").length;
|
|
7074
|
-
if (aDepth !== bDepth)
|
|
7075
|
-
return bDepth - aDepth;
|
|
7076
|
-
const aDynamicCount = a.params.length;
|
|
7077
|
-
const bDynamicCount = b.params.length;
|
|
7078
|
-
if (aDynamicCount !== bDynamicCount)
|
|
7079
|
-
return aDynamicCount - bDynamicCount;
|
|
7080
|
-
return a.pattern.localeCompare(b.pattern);
|
|
7081
|
-
});
|
|
7720
|
+
return routes.sort((a, b) => compareRouteSpecificity(a, b));
|
|
7082
7721
|
}
|
|
7083
7722
|
function generateRouteTree(files) {
|
|
7084
7723
|
const routes = [];
|
|
@@ -7237,26 +7876,38 @@ export function matchRoute(pathname: string): { route: Route; params: Record<str
|
|
|
7237
7876
|
function matchPattern(route: Route, pathname: string): Record<string, string> | null {
|
|
7238
7877
|
const patternParts = route.pattern.split('/').filter(Boolean);
|
|
7239
7878
|
const pathnameParts = pathname.split('/').filter(Boolean);
|
|
7240
|
-
|
|
7241
|
-
if (patternParts.length !== pathnameParts.length) {
|
|
7242
|
-
return null;
|
|
7243
|
-
}
|
|
7244
|
-
|
|
7245
7879
|
const params: Record<string, string> = {};
|
|
7880
|
+
let pathnameIndex = 0;
|
|
7246
7881
|
|
|
7247
7882
|
for (let i = 0; i < patternParts.length; i++) {
|
|
7248
7883
|
const patternPart = patternParts[i];
|
|
7249
|
-
const pathnamePart = pathnameParts[i];
|
|
7250
7884
|
|
|
7251
7885
|
if (patternPart.startsWith(':')) {
|
|
7252
7886
|
const paramName = patternPart.slice(1);
|
|
7887
|
+
if (paramName.startsWith('...')) {
|
|
7888
|
+
if (i !== patternParts.length - 1 || pathnameIndex >= pathnameParts.length) {
|
|
7889
|
+
return null;
|
|
7890
|
+
}
|
|
7891
|
+
|
|
7892
|
+
params[paramName.slice(3)] = pathnameParts.slice(pathnameIndex).join('/');
|
|
7893
|
+
return params;
|
|
7894
|
+
}
|
|
7895
|
+
|
|
7896
|
+
const pathnamePart = pathnameParts[pathnameIndex];
|
|
7897
|
+
if (pathnamePart === undefined) {
|
|
7898
|
+
return null;
|
|
7899
|
+
}
|
|
7900
|
+
|
|
7253
7901
|
params[paramName] = pathnamePart;
|
|
7254
|
-
|
|
7902
|
+
pathnameIndex += 1;
|
|
7903
|
+
} else if (patternPart !== pathnameParts[pathnameIndex]) {
|
|
7255
7904
|
return null;
|
|
7905
|
+
} else {
|
|
7906
|
+
pathnameIndex += 1;
|
|
7256
7907
|
}
|
|
7257
7908
|
}
|
|
7258
7909
|
|
|
7259
|
-
return params;
|
|
7910
|
+
return pathnameIndex === pathnameParts.length ? params : null;
|
|
7260
7911
|
}
|
|
7261
7912
|
|
|
7262
7913
|
// Set globals for compiled binary support (sitemap/RSS/robots discovery)
|
|
@@ -7266,7 +7917,7 @@ function matchPattern(route: Route, pathname: string): Record<string, string> |
|
|
|
7266
7917
|
`;
|
|
7267
7918
|
}
|
|
7268
7919
|
async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
7269
|
-
const streamingDir =
|
|
7920
|
+
const streamingDir = join10(cwd, ".reroute", "streaming");
|
|
7270
7921
|
const analyses = new Map;
|
|
7271
7922
|
const candidates = [
|
|
7272
7923
|
...tree.routes.map((route) => ({
|
|
@@ -7285,7 +7936,7 @@ async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
|
7285
7936
|
for (const candidate of candidates) {
|
|
7286
7937
|
if (!/\.(tsx|ts)$/.test(candidate.filePath))
|
|
7287
7938
|
continue;
|
|
7288
|
-
const absolutePath =
|
|
7939
|
+
const absolutePath = join10(routesPath, candidate.filePath);
|
|
7289
7940
|
const analysis = await analyzeRouteForStreaming({
|
|
7290
7941
|
absolutePath,
|
|
7291
7942
|
relativePath: candidate.filePath,
|
|
@@ -7294,7 +7945,7 @@ async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
|
7294
7945
|
});
|
|
7295
7946
|
if (!analysis.needsStreaming)
|
|
7296
7947
|
continue;
|
|
7297
|
-
const wrapperPath =
|
|
7948
|
+
const wrapperPath = join10(streamingDir, candidate.filePath).replace(/\.(tsx|ts)$/, ".tsx");
|
|
7298
7949
|
await mkdir2(dirname5(wrapperPath), { recursive: true });
|
|
7299
7950
|
const code = await generateStreamingWrapper({
|
|
7300
7951
|
cwd,
|
|
@@ -7311,10 +7962,42 @@ async function buildStreamingWrappersForTree(cwd, routesPath, tree, config2) {
|
|
|
7311
7962
|
}
|
|
7312
7963
|
return analyses;
|
|
7313
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
|
+
}
|
|
7314
7987
|
async function listContentFiles2(collectionDir) {
|
|
7315
7988
|
try {
|
|
7316
|
-
const entries = await
|
|
7317
|
-
|
|
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;
|
|
7318
8001
|
} catch {
|
|
7319
8002
|
return [];
|
|
7320
8003
|
}
|
|
@@ -7371,11 +8054,14 @@ ${spaces}}`;
|
|
|
7371
8054
|
}
|
|
7372
8055
|
return serializeValue(config2);
|
|
7373
8056
|
}
|
|
7374
|
-
async function buildSingleContentChunk(cwd, collection,
|
|
7375
|
-
const
|
|
7376
|
-
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);
|
|
7377
8063
|
const isMarkdown = /\.(md|mdx)$/.test(file);
|
|
7378
|
-
const buildSrc = isMarkdown ?
|
|
8064
|
+
const buildSrc = isMarkdown ? join10(cwd, ".reroute", "markdown", collection, "content", file.replace(/\.(md|mdx)$/, ".tsx")) : absSrc;
|
|
7379
8065
|
if (isMarkdown) {
|
|
7380
8066
|
try {
|
|
7381
8067
|
const exists = await Bun.file(buildSrc).exists();
|
|
@@ -7421,10 +8107,11 @@ async function buildSingleContentChunk(cwd, collection, file, contentDir, args)
|
|
|
7421
8107
|
return null;
|
|
7422
8108
|
}
|
|
7423
8109
|
const hash2 = await sha8(code);
|
|
7424
|
-
const chunkRelDir =
|
|
7425
|
-
const chunkAbsDir =
|
|
7426
|
-
const
|
|
7427
|
-
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);
|
|
7428
8115
|
if (sourcemapContent) {
|
|
7429
8116
|
code = code.replace(/\/\/# sourceMappingURL=.*\.js\.map/, `//# sourceMappingURL=${outFile}.map`);
|
|
7430
8117
|
}
|
|
@@ -7454,26 +8141,27 @@ async function buildSingleContentChunk(cwd, collection, file, contentDir, args)
|
|
|
7454
8141
|
slug: name,
|
|
7455
8142
|
href: `/${collection}/${name}`,
|
|
7456
8143
|
moduleUrl: `/bundles/${outFile}`,
|
|
7457
|
-
meta
|
|
8144
|
+
meta,
|
|
8145
|
+
locale
|
|
7458
8146
|
};
|
|
7459
8147
|
}
|
|
7460
|
-
async function buildContentChunks(cwd, args = []) {
|
|
7461
|
-
const routesRoot =
|
|
8148
|
+
async function buildContentChunks(cwd, args = [], defaultLocale = "en-US") {
|
|
8149
|
+
const routesRoot = join10(cwd, ROUTES_DIR);
|
|
7462
8150
|
console.log(`[reroute/content] scan ${routesRoot}`);
|
|
7463
|
-
const collections2 = await
|
|
8151
|
+
const collections2 = await readdir7(routesRoot, { withFileTypes: true });
|
|
7464
8152
|
const results = [];
|
|
7465
8153
|
for (const c of collections2) {
|
|
7466
8154
|
if (!c.isDirectory())
|
|
7467
8155
|
continue;
|
|
7468
8156
|
const collection = c.name;
|
|
7469
|
-
const contentDir =
|
|
8157
|
+
const contentDir = join10(routesRoot, collection, "content");
|
|
7470
8158
|
console.log(`[reroute/content] collection ${collection} dir ${contentDir}`);
|
|
7471
8159
|
const files = await listContentFiles2(contentDir);
|
|
7472
8160
|
console.log(`[reroute/content] files ${files.length}`);
|
|
7473
8161
|
if (!files.length)
|
|
7474
8162
|
continue;
|
|
7475
8163
|
for (const file of files) {
|
|
7476
|
-
const result = await buildSingleContentChunk(cwd, collection, file, contentDir, args);
|
|
8164
|
+
const result = await buildSingleContentChunk(cwd, collection, file, contentDir, args, defaultLocale);
|
|
7477
8165
|
if (result) {
|
|
7478
8166
|
results.push(result);
|
|
7479
8167
|
}
|
|
@@ -7486,7 +8174,7 @@ async function buildContentChunks(cwd, args = []) {
|
|
|
7486
8174
|
lines.push("");
|
|
7487
8175
|
lines.push("export const contents = [");
|
|
7488
8176
|
for (const e of results) {
|
|
7489
|
-
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 || {}) + " },");
|
|
7490
8178
|
}
|
|
7491
8179
|
lines.push("] as const;");
|
|
7492
8180
|
lines.push("");
|
|
@@ -7494,20 +8182,31 @@ async function buildContentChunks(cwd, args = []) {
|
|
|
7494
8182
|
lines.push("for (const c of contents) { (byCollection[c.collection] ||= []).push(c as any); }");
|
|
7495
8183
|
lines.push("");
|
|
7496
8184
|
lines.push("export const byCollectionAndName: Record<string, Record<string, any>> = {};");
|
|
7497
|
-
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); }");
|
|
7498
8192
|
lines.push("");
|
|
7499
8193
|
lines.push("export type Collections = keyof typeof byCollection;");
|
|
7500
8194
|
lines.push("export type Names<C extends Collections> = keyof (typeof byCollectionAndName)[C];");
|
|
7501
8195
|
lines.push("export type ContentEntry = (typeof contents)[number];");
|
|
7502
8196
|
lines.push("");
|
|
7503
|
-
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(" }");
|
|
7504
8203
|
lines.push(" const m = (byCollectionAndName as any)[collection];");
|
|
7505
8204
|
lines.push(" return m ? (m as Record<string, any>)[name] : undefined;");
|
|
7506
8205
|
lines.push("}");
|
|
7507
8206
|
lines.push("");
|
|
7508
8207
|
const writes = [];
|
|
7509
8208
|
writes.push({
|
|
7510
|
-
path:
|
|
8209
|
+
path: join10(cwd, OUTPUT_CONTENT_TS),
|
|
7511
8210
|
content: lines.join(`
|
|
7512
8211
|
`)
|
|
7513
8212
|
});
|
|
@@ -7519,20 +8218,29 @@ async function buildContentChunks(cwd, args = []) {
|
|
|
7519
8218
|
js.push("");
|
|
7520
8219
|
js.push("export const items = [");
|
|
7521
8220
|
for (const e of items) {
|
|
7522
|
-
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 || {})} },`);
|
|
7523
8222
|
}
|
|
7524
8223
|
js.push("];");
|
|
7525
8224
|
js.push("");
|
|
7526
8225
|
js.push("export const byName = {};");
|
|
7527
|
-
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("}");
|
|
8231
|
+
js.push("");
|
|
8232
|
+
js.push(`export const defaultLocale = ${JSON.stringify(defaultLocale)};`);
|
|
7528
8233
|
js.push("");
|
|
7529
|
-
js.push("export function get(collectionName, name) {");
|
|
8234
|
+
js.push("export function get(collectionName, name, locale) {");
|
|
7530
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(" }");
|
|
7531
8239
|
js.push(" return byName[name];");
|
|
7532
8240
|
js.push("}");
|
|
7533
8241
|
js.push("");
|
|
7534
8242
|
writes.push({
|
|
7535
|
-
path:
|
|
8243
|
+
path: join10(cwd, OUTPUT_COLLECTIONS_DIR, `${collection}.js`),
|
|
7536
8244
|
content: js.join(`
|
|
7537
8245
|
`)
|
|
7538
8246
|
});
|
|
@@ -7556,8 +8264,10 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7556
8264
|
minHeadingLevel = 1,
|
|
7557
8265
|
maxHeadingLevel = 6
|
|
7558
8266
|
} = searchConfig;
|
|
7559
|
-
const routesRoot =
|
|
7560
|
-
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;
|
|
7561
8271
|
const searchIndex = [];
|
|
7562
8272
|
for (const c of collections2) {
|
|
7563
8273
|
if (!c.isDirectory())
|
|
@@ -7566,14 +8276,17 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7566
8276
|
if (targetCollections.length > 0 && !targetCollections.includes(collection)) {
|
|
7567
8277
|
continue;
|
|
7568
8278
|
}
|
|
7569
|
-
const contentDir =
|
|
8279
|
+
const contentDir = join10(routesRoot, collection, "content");
|
|
7570
8280
|
try {
|
|
7571
|
-
const files = await
|
|
7572
|
-
for (const
|
|
8281
|
+
const files = await listContentFiles2(contentDir);
|
|
8282
|
+
for (const fileRef of files) {
|
|
8283
|
+
const file = fileRef.relativePath;
|
|
7573
8284
|
if (!/\.(md|mdx)$/.test(file))
|
|
7574
8285
|
continue;
|
|
7575
|
-
const
|
|
7576
|
-
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);
|
|
7577
8290
|
try {
|
|
7578
8291
|
const processed = processMarkdownFile(filePath);
|
|
7579
8292
|
const { frontmatter, content: content2 } = processed;
|
|
@@ -7587,16 +8300,18 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7587
8300
|
maxLevel: maxHeadingLevel
|
|
7588
8301
|
});
|
|
7589
8302
|
const excerpt = String(frontmatter?.excerpt || frontmatter?.description || stripMarkdown(content2).slice(0, 160));
|
|
8303
|
+
const href = localizeContentHref(collection, name, locale, defaultLocale);
|
|
7590
8304
|
const entry = {
|
|
7591
|
-
id: `${collection}:${name}`,
|
|
8305
|
+
id: locale !== defaultLocale ? `${collection}:${name}:${locale}` : `${collection}:${name}`,
|
|
7592
8306
|
collection,
|
|
7593
8307
|
name,
|
|
7594
8308
|
slug: name,
|
|
7595
|
-
href
|
|
8309
|
+
href,
|
|
7596
8310
|
title: String(frontmatter?.title || name),
|
|
7597
8311
|
excerpt,
|
|
7598
8312
|
headings,
|
|
7599
|
-
meta: {}
|
|
8313
|
+
meta: {},
|
|
8314
|
+
locale
|
|
7600
8315
|
};
|
|
7601
8316
|
for (const field of metaFields) {
|
|
7602
8317
|
if (frontmatter[field] !== undefined) {
|
|
@@ -7619,13 +8334,13 @@ async function buildSearchIndex(cwd, config2, args = []) {
|
|
|
7619
8334
|
generated: new Date().toISOString(),
|
|
7620
8335
|
entries: searchIndex
|
|
7621
8336
|
};
|
|
7622
|
-
await Bun.write(
|
|
7623
|
-
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)}`);
|
|
7624
8339
|
}
|
|
7625
8340
|
async function preprocessMarkdownFiles(cwd, config2) {
|
|
7626
8341
|
console.log("[reroute/markdown] Starting markdown preprocessing...");
|
|
7627
|
-
const routesPath =
|
|
7628
|
-
const markdownDir =
|
|
8342
|
+
const routesPath = join10(cwd, ROUTES_DIR);
|
|
8343
|
+
const markdownDir = join10(cwd, ".reroute", "markdown");
|
|
7629
8344
|
try {
|
|
7630
8345
|
await rm(markdownDir, { force: true, recursive: true });
|
|
7631
8346
|
} catch {}
|
|
@@ -7633,10 +8348,10 @@ async function preprocessMarkdownFiles(cwd, config2) {
|
|
|
7633
8348
|
async function scanMarkdown(dir, base = "") {
|
|
7634
8349
|
const files = [];
|
|
7635
8350
|
try {
|
|
7636
|
-
const entries = await
|
|
8351
|
+
const entries = await readdir7(dir, { withFileTypes: true });
|
|
7637
8352
|
for (const entry of entries) {
|
|
7638
|
-
const fullPath =
|
|
7639
|
-
const relativePath =
|
|
8353
|
+
const fullPath = join10(dir, entry.name);
|
|
8354
|
+
const relativePath = join10(base, entry.name);
|
|
7640
8355
|
if (entry.isDirectory()) {
|
|
7641
8356
|
const nested = await scanMarkdown(fullPath, relativePath);
|
|
7642
8357
|
files.push(...nested);
|
|
@@ -7658,8 +8373,8 @@ async function preprocessMarkdownFiles(cwd, config2) {
|
|
|
7658
8373
|
}
|
|
7659
8374
|
console.log(`[reroute/markdown] Found ${markdownFiles.length} markdown file(s)`);
|
|
7660
8375
|
for (const file of markdownFiles) {
|
|
7661
|
-
const sourcePath =
|
|
7662
|
-
const targetPath =
|
|
8376
|
+
const sourcePath = join10(routesPath, file);
|
|
8377
|
+
const targetPath = join10(markdownDir, file.replace(/\.mdx?$/, ".tsx"));
|
|
7663
8378
|
try {
|
|
7664
8379
|
const processed = processMarkdownFile(sourcePath);
|
|
7665
8380
|
const isMdx = file.endsWith(".mdx");
|
|
@@ -7685,8 +8400,8 @@ async function preprocessMarkdownFiles(cwd, config2) {
|
|
|
7685
8400
|
}
|
|
7686
8401
|
async function buildEntrypointBundle(cwd, args = []) {
|
|
7687
8402
|
const buildStartTime = performance.now();
|
|
7688
|
-
const clientDir =
|
|
7689
|
-
const entrypoint =
|
|
8403
|
+
const clientDir = join10(cwd, "src", "client");
|
|
8404
|
+
const entrypoint = join10(clientDir, "index.tsx");
|
|
7690
8405
|
const exists = await Bun.file(entrypoint).exists();
|
|
7691
8406
|
if (!exists) {
|
|
7692
8407
|
console.log("[reroute/gen] No index.tsx found, skipping bundle build");
|
|
@@ -7694,7 +8409,7 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
7694
8409
|
}
|
|
7695
8410
|
console.log("[reroute/gen] Building entrypoint bundle...");
|
|
7696
8411
|
const isProd = args.includes("--prod");
|
|
7697
|
-
const bundlesDir =
|
|
8412
|
+
const bundlesDir = join10(cwd, ".reroute", "bundles");
|
|
7698
8413
|
await mkdir2(bundlesDir, { recursive: true });
|
|
7699
8414
|
const mode = isProd ? "production" : "development";
|
|
7700
8415
|
const publicEnv = getPublicEnvVars(cwd, mode);
|
|
@@ -7793,10 +8508,10 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
7793
8508
|
}
|
|
7794
8509
|
const newFiles = new Set(outputs.map((o) => o.fileName));
|
|
7795
8510
|
try {
|
|
7796
|
-
const existingFiles = await
|
|
8511
|
+
const existingFiles = await readdir7(bundlesDir);
|
|
7797
8512
|
for (const file of existingFiles) {
|
|
7798
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)$/, ""))) {
|
|
7799
|
-
await rm(
|
|
8514
|
+
await rm(join10(bundlesDir, file), { force: true });
|
|
7800
8515
|
}
|
|
7801
8516
|
}
|
|
7802
8517
|
} catch (_error) {}
|
|
@@ -7812,7 +8527,7 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
7812
8527
|
}
|
|
7813
8528
|
}
|
|
7814
8529
|
await Promise.all(outputs.map(async (output) => {
|
|
7815
|
-
const destPath =
|
|
8530
|
+
const destPath = join10(bundlesDir, output.fileName);
|
|
7816
8531
|
await Bun.write(destPath, output.content);
|
|
7817
8532
|
if (shouldPreCompress) {
|
|
7818
8533
|
const shouldCompress = /\.(js|css)$/i.test(output.fileName) && !output.fileName.endsWith(".map");
|
|
@@ -7881,7 +8596,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7881
8596
|
await writeStubFiles(cwd);
|
|
7882
8597
|
}
|
|
7883
8598
|
await perfTrack("Markdown preprocessing", () => preprocessMarkdownFiles(cwd, config2));
|
|
7884
|
-
const routesPath =
|
|
8599
|
+
const routesPath = join10(cwd, ROUTES_DIR);
|
|
7885
8600
|
try {
|
|
7886
8601
|
await perfTrack("Routes generation", async () => {
|
|
7887
8602
|
const files = await scanDirectory(routesPath);
|
|
@@ -7890,19 +8605,36 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7890
8605
|
const tree = generateRouteTree(all.map((f) => f.replace(/\\/g, "/")));
|
|
7891
8606
|
const streamingAnalyses = streamingEnabled ? await buildStreamingWrappersForTree(cwd, routesPath, tree, config2) : new Map;
|
|
7892
8607
|
const ts = generateTypeScript(tree, streamingAnalyses);
|
|
7893
|
-
await Bun.write(
|
|
8608
|
+
await Bun.write(join10(cwd, OUTPUT_ROUTES), ts);
|
|
7894
8609
|
});
|
|
7895
8610
|
if (!showPerformance) {
|
|
7896
|
-
console.log(`[reroute/gen] Generated routes: ${
|
|
8611
|
+
console.log(`[reroute/gen] Generated routes: ${join10(cwd, OUTPUT_ROUTES)}`);
|
|
7897
8612
|
}
|
|
7898
8613
|
} catch (error) {
|
|
7899
8614
|
console.error("[reroute/gen] Failed to generate routes:", error);
|
|
7900
8615
|
throw error;
|
|
7901
8616
|
}
|
|
8617
|
+
const i18n2 = await discoverI18n(cwd, config2.i18n);
|
|
8618
|
+
const defaultLocale = i18n2.defaultLocale;
|
|
7902
8619
|
try {
|
|
7903
|
-
await
|
|
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
|
+
}
|
|
8634
|
+
try {
|
|
8635
|
+
await perfTrack("Content building", () => buildContentChunks(cwd, args, defaultLocale));
|
|
7904
8636
|
if (!showPerformance) {
|
|
7905
|
-
console.log(`[reroute/gen] Generated content: ${
|
|
8637
|
+
console.log(`[reroute/gen] Generated content: ${join10(cwd, OUTPUT_CONTENT_TS)} + collections/*.js`);
|
|
7906
8638
|
}
|
|
7907
8639
|
} catch (error) {
|
|
7908
8640
|
console.error("[reroute/gen] Failed to generate content:", error);
|
|
@@ -7910,22 +8642,25 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7910
8642
|
}
|
|
7911
8643
|
try {
|
|
7912
8644
|
await perfTrack("Manifest generation", async () => {
|
|
7913
|
-
const routesPath2 =
|
|
8645
|
+
const routesPath2 = join10(cwd, OUTPUT_ROUTES);
|
|
7914
8646
|
const routesModule = await import(`file://${routesPath2}?t=${Date.now()}`);
|
|
7915
8647
|
const routes = routesModule.routes || [];
|
|
7916
8648
|
const staticRoutes = routes.filter((r) => !r.params || r.params.length === 0).map((r) => r.pattern);
|
|
7917
8649
|
const contentRoutes = [];
|
|
7918
|
-
const collectionsDir =
|
|
8650
|
+
const collectionsDir = join10(cwd, ".reroute", "collections");
|
|
7919
8651
|
try {
|
|
7920
|
-
const collectionFiles = await
|
|
8652
|
+
const collectionFiles = await readdir7(collectionsDir);
|
|
7921
8653
|
for (const file of collectionFiles) {
|
|
7922
8654
|
if (file.endsWith(".js")) {
|
|
7923
|
-
const collectionPath =
|
|
8655
|
+
const collectionPath = join10(collectionsDir, file);
|
|
7924
8656
|
const collectionModule = await import(`file://${collectionPath}?t=${Date.now()}`);
|
|
7925
8657
|
const items = collectionModule.items || [];
|
|
7926
8658
|
for (const item of items) {
|
|
7927
8659
|
if (item.href) {
|
|
7928
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
|
+
}
|
|
7929
8664
|
}
|
|
7930
8665
|
}
|
|
7931
8666
|
}
|
|
@@ -7942,7 +8677,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7942
8677
|
dynamicRoutes,
|
|
7943
8678
|
version: 1
|
|
7944
8679
|
};
|
|
7945
|
-
await Bun.write(
|
|
8680
|
+
await Bun.write(join10(cwd, ".reroute", "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
7946
8681
|
});
|
|
7947
8682
|
} catch (error) {
|
|
7948
8683
|
console.error("[reroute/gen] Failed to generate manifest:", error);
|
|
@@ -7963,7 +8698,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7963
8698
|
mdComponentsLines.push("");
|
|
7964
8699
|
mdComponentsLines.push(`import markdownComponents from '${componentsPath}';`);
|
|
7965
8700
|
mdComponentsLines.push("export { markdownComponents };");
|
|
7966
|
-
await Bun.write(
|
|
8701
|
+
await Bun.write(join10(cwd, ".reroute/markdown-components.ts"), mdComponentsLines.join(`
|
|
7967
8702
|
`));
|
|
7968
8703
|
}
|
|
7969
8704
|
const indexLines = [];
|
|
@@ -7983,7 +8718,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
7983
8718
|
const ogTemplatePath = config2.ogImage.defaultTemplate.startsWith(".") ? `../${config2.ogImage.defaultTemplate}` : config2.ogImage.defaultTemplate;
|
|
7984
8719
|
indexLines.push(`import OGTemplate from '${ogTemplatePath}';`);
|
|
7985
8720
|
}
|
|
7986
|
-
const ogFiles = await scanOgFiles(
|
|
8721
|
+
const ogFiles = await scanOgFiles(join10(cwd, ROUTES_DIR));
|
|
7987
8722
|
const ogImports = [];
|
|
7988
8723
|
for (let i = 0;i < ogFiles.length; i++) {
|
|
7989
8724
|
const ogFile = ogFiles[i];
|
|
@@ -8029,7 +8764,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8029
8764
|
}
|
|
8030
8765
|
indexLines.push("};");
|
|
8031
8766
|
}
|
|
8032
|
-
const templatePath =
|
|
8767
|
+
const templatePath = join10(cwd, "src", "client", "index.html");
|
|
8033
8768
|
try {
|
|
8034
8769
|
const templateContent = await Bun.file(templatePath).text();
|
|
8035
8770
|
indexLines.push("");
|
|
@@ -8041,7 +8776,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8041
8776
|
indexLines.push(`(globalThis as any).__REROUTE_CONFIG__ = ${serializeConfig(config2)};`);
|
|
8042
8777
|
indexLines.push("");
|
|
8043
8778
|
indexLines.push("export type RerouteBundle = typeof bundle;");
|
|
8044
|
-
await Bun.write(
|
|
8779
|
+
await Bun.write(join10(cwd, OUTPUT_ARTIFACTS), indexLines.join(`
|
|
8045
8780
|
`));
|
|
8046
8781
|
const barrelLines = [
|
|
8047
8782
|
"// \uD83D\uDEA8 Auto-generated by Reroute - DO NOT EDIT \uD83D\uDEA8",
|
|
@@ -8051,7 +8786,7 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8051
8786
|
"",
|
|
8052
8787
|
"export * from './artifacts';"
|
|
8053
8788
|
];
|
|
8054
|
-
await Bun.write(
|
|
8789
|
+
await Bun.write(join10(cwd, OUTPUT_INDEX), barrelLines.join(`
|
|
8055
8790
|
`));
|
|
8056
8791
|
const entryLines = [
|
|
8057
8792
|
"// \uD83D\uDEA8 Auto-generated by Reroute - DO NOT EDIT \uD83D\uDEA8",
|
|
@@ -8067,10 +8802,10 @@ async function generate(cwd, args = [], options = {}) {
|
|
|
8067
8802
|
"import './routes'; // Import routes (bundles all route components)",
|
|
8068
8803
|
"import '../src/index'; // Import user's server entry"
|
|
8069
8804
|
];
|
|
8070
|
-
await Bun.write(
|
|
8805
|
+
await Bun.write(join10(cwd, ".reroute/entry.ts"), entryLines.join(`
|
|
8071
8806
|
`));
|
|
8072
8807
|
if (!showPerformance) {
|
|
8073
|
-
console.log(`[reroute/gen] Generated artifacts: ${
|
|
8808
|
+
console.log(`[reroute/gen] Generated artifacts: ${join10(cwd, OUTPUT_ARTIFACTS)}`);
|
|
8074
8809
|
}
|
|
8075
8810
|
await perfTrack("Bundle building", () => buildEntrypointBundle(cwd, args));
|
|
8076
8811
|
const endTime = performance.now();
|
|
@@ -8197,7 +8932,7 @@ async function gen(args) {
|
|
|
8197
8932
|
const mediumDebounce = createDebouncer(150);
|
|
8198
8933
|
const slowDebounce = createDebouncer(300);
|
|
8199
8934
|
const loadedConfig = await loadConfig(cwd);
|
|
8200
|
-
const configPath =
|
|
8935
|
+
const configPath = join10(cwd, "reroute.config.ts");
|
|
8201
8936
|
let configWatcher = null;
|
|
8202
8937
|
try {
|
|
8203
8938
|
configWatcher = watch(configPath, () => {
|
|
@@ -8219,7 +8954,7 @@ async function gen(args) {
|
|
|
8219
8954
|
];
|
|
8220
8955
|
const envWatchers = [];
|
|
8221
8956
|
for (const envFile of envFiles) {
|
|
8222
|
-
const envPath =
|
|
8957
|
+
const envPath = join10(cwd, envFile);
|
|
8223
8958
|
try {
|
|
8224
8959
|
const envWatcher = watch(envPath, () => {
|
|
8225
8960
|
mediumDebounce(() => {
|
|
@@ -8238,15 +8973,15 @@ async function gen(args) {
|
|
|
8238
8973
|
let packagesWatcher = null;
|
|
8239
8974
|
const isRerouteWorkspace = async () => {
|
|
8240
8975
|
try {
|
|
8241
|
-
const packagesPath =
|
|
8242
|
-
const exists = await Bun.file(
|
|
8976
|
+
const packagesPath = join10(cwd, "..", "..", "packages");
|
|
8977
|
+
const exists = await Bun.file(join10(packagesPath, "core", "index.ts")).exists();
|
|
8243
8978
|
return exists;
|
|
8244
8979
|
} catch {
|
|
8245
8980
|
return false;
|
|
8246
8981
|
}
|
|
8247
8982
|
};
|
|
8248
8983
|
if (await isRerouteWorkspace()) {
|
|
8249
|
-
const packagesPath =
|
|
8984
|
+
const packagesPath = join10(cwd, "..", "..", "packages");
|
|
8250
8985
|
console.log("[reroute/watch] \uD83D\uDD27 Workspace development mode enabled");
|
|
8251
8986
|
console.log(`[reroute/watch] \uD83D\uDD27 Watching ${packagesPath}...`);
|
|
8252
8987
|
packagesWatcher = watch(packagesPath, { recursive: true }, (_ev, filename) => {
|
|
@@ -8269,7 +9004,7 @@ async function gen(args) {
|
|
|
8269
9004
|
});
|
|
8270
9005
|
});
|
|
8271
9006
|
}
|
|
8272
|
-
const routesPath =
|
|
9007
|
+
const routesPath = join10(cwd, ROUTES_DIR);
|
|
8273
9008
|
console.log(`[reroute/watch] \uD83D\uDCC1 Watching ${routesPath}...`);
|
|
8274
9009
|
const routesWatcher = watch(routesPath, { recursive: true }, (_ev, filename) => {
|
|
8275
9010
|
if (!filename)
|
|
@@ -8291,7 +9026,16 @@ async function gen(args) {
|
|
|
8291
9026
|
}
|
|
8292
9027
|
console.log("[reroute/watch] ├─ Building content chunks...");
|
|
8293
9028
|
const contentStart = performance.now();
|
|
8294
|
-
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);
|
|
8295
9039
|
const contentTime = ((performance.now() - contentStart) / 1000).toFixed(2);
|
|
8296
9040
|
console.log(`[reroute/watch] └─ Content: ${contentTime}s`);
|
|
8297
9041
|
if (loadedConfig.search?.enabled) {
|
|
@@ -8320,7 +9064,7 @@ async function gen(args) {
|
|
|
8320
9064
|
}, "routes change");
|
|
8321
9065
|
});
|
|
8322
9066
|
});
|
|
8323
|
-
const clientPath =
|
|
9067
|
+
const clientPath = join10(cwd, "src", "client");
|
|
8324
9068
|
console.log(`[reroute/watch] \uD83D\uDCE6 Watching ${clientPath}...`);
|
|
8325
9069
|
const twWatcher = watch(clientPath, { recursive: true }, (_ev, filename) => {
|
|
8326
9070
|
if (!filename)
|
|
@@ -13178,7 +13922,7 @@ var require_program = __commonJS((exports, module) => {
|
|
|
13178
13922
|
}
|
|
13179
13923
|
break;
|
|
13180
13924
|
case "underline":
|
|
13181
|
-
if (!blink) {}
|
|
13925
|
+
if (!blink) {}
|
|
13182
13926
|
break;
|
|
13183
13927
|
case "line":
|
|
13184
13928
|
if (!blink) {
|
|
@@ -100442,7 +101186,7 @@ var require_lodash = __commonJS((exports, module) => {
|
|
|
100442
101186
|
}
|
|
100443
101187
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
100444
101188
|
});
|
|
100445
|
-
function
|
|
101189
|
+
function join11(array, separator) {
|
|
100446
101190
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
100447
101191
|
}
|
|
100448
101192
|
function last(array) {
|
|
@@ -102374,7 +103118,7 @@ __p += '`;
|
|
|
102374
103118
|
lodash.isUndefined = isUndefined;
|
|
102375
103119
|
lodash.isWeakMap = isWeakMap;
|
|
102376
103120
|
lodash.isWeakSet = isWeakSet;
|
|
102377
|
-
lodash.join =
|
|
103121
|
+
lodash.join = join11;
|
|
102378
103122
|
lodash.kebabCase = kebabCase;
|
|
102379
103123
|
lodash.last = last;
|
|
102380
103124
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -103056,19 +103800,19 @@ __export(exports_dev, {
|
|
|
103056
103800
|
});
|
|
103057
103801
|
import { spawn as spawn2 } from "node:child_process";
|
|
103058
103802
|
import { existsSync as existsSync6 } from "node:fs";
|
|
103059
|
-
import { join as
|
|
103803
|
+
import { join as join11 } from "node:path";
|
|
103060
103804
|
function getRerouteCommand() {
|
|
103061
|
-
const binPath =
|
|
103805
|
+
const binPath = join11(import.meta.dir, "..", "..", "bin.ts");
|
|
103062
103806
|
const isBunDev = existsSync6(binPath);
|
|
103063
103807
|
if (isBunDev) {
|
|
103064
103808
|
return `bun ${binPath}`;
|
|
103065
103809
|
}
|
|
103066
103810
|
const cwd = process.cwd();
|
|
103067
103811
|
const nodeModulesPaths = [
|
|
103068
|
-
|
|
103069
|
-
|
|
103070
|
-
|
|
103071
|
-
|
|
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")
|
|
103072
103816
|
];
|
|
103073
103817
|
for (const binPath2 of nodeModulesPaths) {
|
|
103074
103818
|
if (existsSync6(binPath2)) {
|
|
@@ -103224,19 +103968,19 @@ __export(exports_start, {
|
|
|
103224
103968
|
});
|
|
103225
103969
|
import { spawn as spawn3 } from "node:child_process";
|
|
103226
103970
|
import { existsSync as existsSync7 } from "node:fs";
|
|
103227
|
-
import { join as
|
|
103971
|
+
import { join as join12 } from "node:path";
|
|
103228
103972
|
function getRerouteCommand2() {
|
|
103229
|
-
const binPath =
|
|
103973
|
+
const binPath = join12(import.meta.dir, "..", "..", "bin.ts");
|
|
103230
103974
|
const isBunDev = existsSync7(binPath);
|
|
103231
103975
|
if (isBunDev) {
|
|
103232
103976
|
return `bun ${binPath}`;
|
|
103233
103977
|
}
|
|
103234
103978
|
const cwd = process.cwd();
|
|
103235
103979
|
const nodeModulesPaths = [
|
|
103236
|
-
|
|
103237
|
-
|
|
103238
|
-
|
|
103239
|
-
|
|
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")
|
|
103240
103984
|
];
|
|
103241
103985
|
for (const binPath2 of nodeModulesPaths) {
|
|
103242
103986
|
if (existsSync7(binPath2)) {
|
|
@@ -103364,12 +104108,12 @@ import {
|
|
|
103364
104108
|
mkdirSync,
|
|
103365
104109
|
readdirSync
|
|
103366
104110
|
} from "node:fs";
|
|
103367
|
-
import { join as
|
|
104111
|
+
import { join as join13 } from "node:path";
|
|
103368
104112
|
function copyAssetsToReroute(cwd, sourceAssetsDir, rerouteAssetsDir) {
|
|
103369
104113
|
if (!existsSync8(sourceAssetsDir)) {
|
|
103370
104114
|
return 0;
|
|
103371
104115
|
}
|
|
103372
|
-
const rerouteDir =
|
|
104116
|
+
const rerouteDir = join13(cwd, ".reroute");
|
|
103373
104117
|
if (!existsSync8(rerouteDir)) {
|
|
103374
104118
|
mkdirSync(rerouteDir, { recursive: true });
|
|
103375
104119
|
}
|
|
@@ -103381,7 +104125,7 @@ function countFiles(dir) {
|
|
|
103381
104125
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
103382
104126
|
for (const entry of entries) {
|
|
103383
104127
|
if (entry.isDirectory()) {
|
|
103384
|
-
count += countFiles(
|
|
104128
|
+
count += countFiles(join13(dir, entry.name));
|
|
103385
104129
|
} else {
|
|
103386
104130
|
count++;
|
|
103387
104131
|
}
|
|
@@ -103397,19 +104141,19 @@ __export(exports_build, {
|
|
|
103397
104141
|
});
|
|
103398
104142
|
import { spawn as spawn4 } from "node:child_process";
|
|
103399
104143
|
import { existsSync as existsSync9, readFileSync as readFileSync5, rmSync, unlinkSync } from "node:fs";
|
|
103400
|
-
import { join as
|
|
104144
|
+
import { join as join14 } from "node:path";
|
|
103401
104145
|
function getRerouteCommand3() {
|
|
103402
|
-
const binPath =
|
|
104146
|
+
const binPath = join14(import.meta.dir, "..", "..", "bin.ts");
|
|
103403
104147
|
const isBunDev = existsSync9(binPath);
|
|
103404
104148
|
if (isBunDev) {
|
|
103405
104149
|
return `bun ${binPath}`;
|
|
103406
104150
|
}
|
|
103407
104151
|
const cwd = process.cwd();
|
|
103408
104152
|
const nodeModulesPaths = [
|
|
103409
|
-
|
|
103410
|
-
|
|
103411
|
-
|
|
103412
|
-
|
|
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")
|
|
103413
104157
|
];
|
|
103414
104158
|
for (const binPath2 of nodeModulesPaths) {
|
|
103415
104159
|
if (existsSync9(binPath2)) {
|
|
@@ -103420,7 +104164,7 @@ function getRerouteCommand3() {
|
|
|
103420
104164
|
}
|
|
103421
104165
|
function getOutputName() {
|
|
103422
104166
|
const cwd = process.cwd();
|
|
103423
|
-
const packageJsonPath =
|
|
104167
|
+
const packageJsonPath = join14(cwd, "package.json");
|
|
103424
104168
|
if (existsSync9(packageJsonPath)) {
|
|
103425
104169
|
try {
|
|
103426
104170
|
const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
@@ -103452,7 +104196,7 @@ function parseBuildArgs(args) {
|
|
|
103452
104196
|
return { outfile, compileBinary, noCompression, externalArgs };
|
|
103453
104197
|
}
|
|
103454
104198
|
function cleanDistFolder(cwd) {
|
|
103455
|
-
const distDir =
|
|
104199
|
+
const distDir = join14(cwd, "dist");
|
|
103456
104200
|
if (existsSync9(distDir)) {
|
|
103457
104201
|
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Cleaning dist folder...
|
|
103458
104202
|
`));
|
|
@@ -103460,7 +104204,7 @@ function cleanDistFolder(cwd) {
|
|
|
103460
104204
|
}
|
|
103461
104205
|
}
|
|
103462
104206
|
async function cleanRerouteFolder(cwd) {
|
|
103463
|
-
const rerouteDir =
|
|
104207
|
+
const rerouteDir = join14(cwd, ".reroute");
|
|
103464
104208
|
if (existsSync9(rerouteDir)) {
|
|
103465
104209
|
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Cleaning .reroute folder...
|
|
103466
104210
|
`));
|
|
@@ -103517,8 +104261,8 @@ async function copyAssets(cwd) {
|
|
|
103517
104261
|
const appSrc = config2.app?.src ?? "./src/client/App";
|
|
103518
104262
|
const dirname6 = __require("node:path").dirname;
|
|
103519
104263
|
const assetsPath = dirname6(appSrc);
|
|
103520
|
-
const sourceAssetsDir =
|
|
103521
|
-
const rerouteAssetsDir =
|
|
104264
|
+
const sourceAssetsDir = join14(cwd, assetsPath, "assets");
|
|
104265
|
+
const rerouteAssetsDir = join14(cwd, ".reroute", "assets");
|
|
103522
104266
|
process.stdout.write(colorizeLogPrefixAnsi(`[reroute/build] Copying assets...
|
|
103523
104267
|
`));
|
|
103524
104268
|
const fileCount = copyAssetsToReroute(cwd, sourceAssetsDir, rerouteAssetsDir);
|
|
@@ -103533,9 +104277,9 @@ async function copyAssets(cwd) {
|
|
|
103533
104277
|
async function buildBundle(cwd, buildArgs) {
|
|
103534
104278
|
const external = [...buildArgs.externalArgs, "sharp", "@vercel/og"];
|
|
103535
104279
|
const buildResult = await Bun.build({
|
|
103536
|
-
entrypoints: [
|
|
104280
|
+
entrypoints: [join14(cwd, ".reroute/entry.ts")],
|
|
103537
104281
|
target: "bun",
|
|
103538
|
-
outdir:
|
|
104282
|
+
outdir: join14(cwd, "dist"),
|
|
103539
104283
|
sourcemap: "external",
|
|
103540
104284
|
...getCommonBuildOptions(),
|
|
103541
104285
|
external,
|
|
@@ -103578,7 +104322,7 @@ function cleanupBundledFiles(rerouteDir) {
|
|
|
103578
104322
|
"markdown-components.ts"
|
|
103579
104323
|
];
|
|
103580
104324
|
for (const file of tsFilesToRemove) {
|
|
103581
|
-
const filePath =
|
|
104325
|
+
const filePath = join14(rerouteDir, file);
|
|
103582
104326
|
if (existsSync9(filePath)) {
|
|
103583
104327
|
try {
|
|
103584
104328
|
unlinkSync(filePath);
|
|
@@ -103588,7 +104332,7 @@ function cleanupBundledFiles(rerouteDir) {
|
|
|
103588
104332
|
}
|
|
103589
104333
|
const dirsToRemove = ["markdown", "streaming"];
|
|
103590
104334
|
for (const dir of dirsToRemove) {
|
|
103591
|
-
const dirPath =
|
|
104335
|
+
const dirPath = join14(rerouteDir, dir);
|
|
103592
104336
|
if (existsSync9(dirPath)) {
|
|
103593
104337
|
try {
|
|
103594
104338
|
rmSync(dirPath, { recursive: true });
|
|
@@ -103622,7 +104366,7 @@ async function build(args) {
|
|
|
103622
104366
|
await runGenCommand(rerouteCmd, useShell, buildArgs.noCompression);
|
|
103623
104367
|
await copyAssets(cwd);
|
|
103624
104368
|
await buildBundle(cwd, buildArgs);
|
|
103625
|
-
const rerouteDir =
|
|
104369
|
+
const rerouteDir = join14(cwd, ".reroute");
|
|
103626
104370
|
cleanupBundledFiles(rerouteDir);
|
|
103627
104371
|
logBuildComplete(buildStartTime, buildArgs);
|
|
103628
104372
|
process.exit(0);
|
|
@@ -103644,19 +104388,19 @@ __export(exports_command, {
|
|
|
103644
104388
|
getRerouteCommand: () => getRerouteCommand4
|
|
103645
104389
|
});
|
|
103646
104390
|
import { existsSync as existsSync10 } from "node:fs";
|
|
103647
|
-
import { join as
|
|
104391
|
+
import { join as join15 } from "node:path";
|
|
103648
104392
|
function getRerouteCommand4() {
|
|
103649
|
-
const binPath =
|
|
104393
|
+
const binPath = join15(import.meta.dir, "..", "..", "bin.ts");
|
|
103650
104394
|
const isBunDev = existsSync10(binPath);
|
|
103651
104395
|
if (isBunDev) {
|
|
103652
104396
|
return `bun ${binPath}`;
|
|
103653
104397
|
}
|
|
103654
104398
|
const cwd = process.cwd();
|
|
103655
104399
|
const nodeModulesPaths = [
|
|
103656
|
-
|
|
103657
|
-
|
|
103658
|
-
|
|
103659
|
-
|
|
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")
|
|
103660
104404
|
];
|
|
103661
104405
|
for (const binPath2 of nodeModulesPaths) {
|
|
103662
104406
|
if (existsSync10(binPath2)) {
|
|
@@ -103673,24 +104417,24 @@ __export(exports_analyze, {
|
|
|
103673
104417
|
default: () => analyze
|
|
103674
104418
|
});
|
|
103675
104419
|
import { existsSync as existsSync11, statSync } from "node:fs";
|
|
103676
|
-
import { readdir as
|
|
103677
|
-
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";
|
|
103678
104422
|
import Table from "cli-table3";
|
|
103679
104423
|
async function findChunkBundles(cwd) {
|
|
103680
104424
|
const bundles = [];
|
|
103681
|
-
const chunksDir =
|
|
104425
|
+
const chunksDir = join16(cwd, ".reroute", "chunks");
|
|
103682
104426
|
if (!existsSync11(chunksDir))
|
|
103683
104427
|
return bundles;
|
|
103684
|
-
const collections2 = await
|
|
104428
|
+
const collections2 = await readdir8(chunksDir, { withFileTypes: true });
|
|
103685
104429
|
for (const collection of collections2) {
|
|
103686
104430
|
if (!collection.isDirectory())
|
|
103687
104431
|
continue;
|
|
103688
|
-
const collectionDir =
|
|
103689
|
-
const files = await
|
|
104432
|
+
const collectionDir = join16(chunksDir, collection.name);
|
|
104433
|
+
const files = await readdir8(collectionDir);
|
|
103690
104434
|
for (const file of files) {
|
|
103691
104435
|
if (!file.endsWith(".js"))
|
|
103692
104436
|
continue;
|
|
103693
|
-
const filePath =
|
|
104437
|
+
const filePath = join16(collectionDir, file);
|
|
103694
104438
|
const stats = await stat5(filePath);
|
|
103695
104439
|
const content2 = await Bun.file(filePath).arrayBuffer();
|
|
103696
104440
|
const gzippedSize = Bun.gzipSync(new Uint8Array(content2)).length;
|
|
@@ -103708,12 +104452,12 @@ async function findChunkBundles(cwd) {
|
|
|
103708
104452
|
}
|
|
103709
104453
|
async function findDistBundles(cwd) {
|
|
103710
104454
|
const bundles = [];
|
|
103711
|
-
const distDir =
|
|
104455
|
+
const distDir = join16(cwd, "dist");
|
|
103712
104456
|
if (!existsSync11(distDir))
|
|
103713
104457
|
return bundles;
|
|
103714
|
-
const files = await
|
|
104458
|
+
const files = await readdir8(distDir);
|
|
103715
104459
|
for (const file of files) {
|
|
103716
|
-
const filePath =
|
|
104460
|
+
const filePath = join16(distDir, file);
|
|
103717
104461
|
const stats = statSync(filePath);
|
|
103718
104462
|
if (stats.isFile() && !file.endsWith(".map") && !file.endsWith(".d.ts")) {
|
|
103719
104463
|
const content2 = await Bun.file(filePath).arrayBuffer();
|
|
@@ -103739,9 +104483,9 @@ async function findBundles(cwd) {
|
|
|
103739
104483
|
}
|
|
103740
104484
|
async function findBrowserEntry(cwd) {
|
|
103741
104485
|
try {
|
|
103742
|
-
const clientDir =
|
|
103743
|
-
const tsxEntry =
|
|
103744
|
-
const tsEntry =
|
|
104486
|
+
const clientDir = join16(cwd, "src", "client");
|
|
104487
|
+
const tsxEntry = join16(clientDir, "index.tsx");
|
|
104488
|
+
const tsEntry = join16(clientDir, "index.ts");
|
|
103745
104489
|
let sourceEntry = null;
|
|
103746
104490
|
if (existsSync11(tsxEntry)) {
|
|
103747
104491
|
sourceEntry = tsxEntry;
|
|
@@ -103774,12 +104518,12 @@ async function findBrowserEntry(cwd) {
|
|
|
103774
104518
|
console.warn("[reroute/analyze] Browser build produced no outputs");
|
|
103775
104519
|
return null;
|
|
103776
104520
|
}
|
|
103777
|
-
const tempDir =
|
|
104521
|
+
const tempDir = join16(cwd, ".reroute", "browser");
|
|
103778
104522
|
await import("node:fs/promises").then((fs) => fs.mkdir(tempDir, { recursive: true }));
|
|
103779
104523
|
const output = result.outputs[0];
|
|
103780
104524
|
const code = await output.text();
|
|
103781
104525
|
const actualHash = await generateContentHash2(code);
|
|
103782
|
-
const bundlePath =
|
|
104526
|
+
const bundlePath = join16(tempDir, `index.${actualHash}.js`);
|
|
103783
104527
|
await writeFile(bundlePath, code, "utf-8");
|
|
103784
104528
|
const mapOutput = result.outputs.find((o) => o.path.endsWith(".map"));
|
|
103785
104529
|
if (mapOutput) {
|
|
@@ -103831,7 +104575,7 @@ function calculateStats(bundles) {
|
|
|
103831
104575
|
}
|
|
103832
104576
|
async function getInstalledPackageSizes(cwd) {
|
|
103833
104577
|
const packageSizes = new Map;
|
|
103834
|
-
const nodeModulesDir =
|
|
104578
|
+
const nodeModulesDir = join16(cwd, "node_modules");
|
|
103835
104579
|
if (!existsSync11(nodeModulesDir))
|
|
103836
104580
|
return packageSizes;
|
|
103837
104581
|
try {
|
|
@@ -103887,7 +104631,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
103887
104631
|
if (!pkgNode) {
|
|
103888
104632
|
pkgNode = {
|
|
103889
104633
|
name: pkgName || "unknown",
|
|
103890
|
-
path:
|
|
104634
|
+
path: join16(cwd, "node_modules", pkgName || ""),
|
|
103891
104635
|
size: 0,
|
|
103892
104636
|
children: []
|
|
103893
104637
|
};
|
|
@@ -103908,7 +104652,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
103908
104652
|
if (!child) {
|
|
103909
104653
|
child = {
|
|
103910
104654
|
name: part,
|
|
103911
|
-
path:
|
|
104655
|
+
path: join16(cwd, ...parts.slice(0, i + 1)),
|
|
103912
104656
|
size: 0,
|
|
103913
104657
|
children: []
|
|
103914
104658
|
};
|
|
@@ -103939,7 +104683,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
103939
104683
|
const modulePattern = /\/\/\s*(.+?\.(?:ts|tsx|js|jsx|mjs|cjs))\s*$/gm;
|
|
103940
104684
|
const nodeModulesNode = {
|
|
103941
104685
|
name: "node_modules",
|
|
103942
|
-
path:
|
|
104686
|
+
path: join16(cwd, "node_modules"),
|
|
103943
104687
|
size: 0,
|
|
103944
104688
|
children: []
|
|
103945
104689
|
};
|
|
@@ -104005,7 +104749,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104005
104749
|
if (sourcePath.startsWith("/") || sourcePath.match(/^[A-Za-z]:\\/))
|
|
104006
104750
|
return sourcePath;
|
|
104007
104751
|
const bundleDir = bundlePath.substring(0, bundlePath.lastIndexOf("/"));
|
|
104008
|
-
return
|
|
104752
|
+
return join16(bundleDir, sourceRoot || "", sourcePath);
|
|
104009
104753
|
}, computeSizes = function(node) {
|
|
104010
104754
|
if (node.children && node.children.length > 0) {
|
|
104011
104755
|
node.size = node.children.reduce((s, c) => s + computeSizes(c), 0);
|
|
@@ -104077,7 +104821,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104077
104821
|
};
|
|
104078
104822
|
const nodeModulesNode = {
|
|
104079
104823
|
name: "node_modules",
|
|
104080
|
-
path:
|
|
104824
|
+
path: join16(cwd, "node_modules"),
|
|
104081
104825
|
size: 0,
|
|
104082
104826
|
children: []
|
|
104083
104827
|
};
|
|
@@ -104117,7 +104861,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104117
104861
|
if (!pkgNode) {
|
|
104118
104862
|
pkgNode = {
|
|
104119
104863
|
name: pkgName || "unknown",
|
|
104120
|
-
path:
|
|
104864
|
+
path: join16(cwd, "node_modules", pkgName || ""),
|
|
104121
104865
|
size: 0,
|
|
104122
104866
|
children: []
|
|
104123
104867
|
};
|
|
@@ -104138,7 +104882,7 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
104138
104882
|
if (!child) {
|
|
104139
104883
|
child = {
|
|
104140
104884
|
name: part,
|
|
104141
|
-
path:
|
|
104885
|
+
path: join16(cwd, ...parts.slice(0, i2 + 1)),
|
|
104142
104886
|
size: 0,
|
|
104143
104887
|
children: []
|
|
104144
104888
|
};
|
|
@@ -104168,11 +104912,11 @@ async function generateHTMLReport(stats, depTree, mainInfo, browserDepTree, brow
|
|
|
104168
104912
|
let actualServerBinarySize = null;
|
|
104169
104913
|
let actualServerBinaryGzipped = null;
|
|
104170
104914
|
try {
|
|
104171
|
-
const distDir =
|
|
104915
|
+
const distDir = join16(process.cwd(), "dist");
|
|
104172
104916
|
if (existsSync11(distDir)) {
|
|
104173
|
-
const files = await
|
|
104917
|
+
const files = await readdir8(distDir);
|
|
104174
104918
|
for (const file of files) {
|
|
104175
|
-
const filePath =
|
|
104919
|
+
const filePath = join16(distDir, file);
|
|
104176
104920
|
const stats2 = statSync(filePath);
|
|
104177
104921
|
if (stats2.isFile() && !file.includes(".")) {
|
|
104178
104922
|
actualServerBinarySize = stats2.size;
|
|
@@ -105654,11 +106398,11 @@ async function printConsoleReport(stats, depTree, mainInfo, browserDepTree, brow
|
|
|
105654
106398
|
let actualServerBinarySize = null;
|
|
105655
106399
|
let actualServerBinaryGzipped = null;
|
|
105656
106400
|
try {
|
|
105657
|
-
const distDir =
|
|
106401
|
+
const distDir = join16(process.cwd(), "dist");
|
|
105658
106402
|
if (existsSync11(distDir)) {
|
|
105659
|
-
const files = await
|
|
106403
|
+
const files = await readdir8(distDir);
|
|
105660
106404
|
for (const file of files) {
|
|
105661
|
-
const filePath =
|
|
106405
|
+
const filePath = join16(distDir, file);
|
|
105662
106406
|
const stats2 = statSync(filePath);
|
|
105663
106407
|
if (stats2.isFile() && !file.includes(".")) {
|
|
105664
106408
|
actualServerBinarySize = stats2.size;
|
|
@@ -105692,7 +106436,7 @@ async function analyze(args) {
|
|
|
105692
106436
|
const isProd = isProductionMode(args);
|
|
105693
106437
|
const searchIndex = args.indexOf("--search");
|
|
105694
106438
|
const initialSearch = searchIndex !== -1 && args[searchIndex + 1] ? args[searchIndex + 1] : "";
|
|
105695
|
-
const rerouteIndexPath =
|
|
106439
|
+
const rerouteIndexPath = join16(cwd, ".reroute", "index.ts");
|
|
105696
106440
|
if (!existsSync11(rerouteIndexPath)) {
|
|
105697
106441
|
console.log(colorizeLogPrefixAnsi(`[reroute/analyze] .reroute artifacts not found, running build...
|
|
105698
106442
|
`));
|
|
@@ -105755,12 +106499,12 @@ async function analyze(args) {
|
|
|
105755
106499
|
let entry = null;
|
|
105756
106500
|
let depTree = null;
|
|
105757
106501
|
let mainInfo = null;
|
|
105758
|
-
const srcEntry =
|
|
106502
|
+
const srcEntry = join16(cwd, "src", "index.ts");
|
|
105759
106503
|
if (existsSync11(srcEntry)) {
|
|
105760
106504
|
console.log(colorizeLogPrefixAnsi(`[reroute/analyze] Building server binary for analysis...
|
|
105761
106505
|
`));
|
|
105762
106506
|
const { mkdir: mkdir3 } = await import("node:fs/promises");
|
|
105763
|
-
const serverAnalysisDir =
|
|
106507
|
+
const serverAnalysisDir = join16(cwd, ".reroute", "server");
|
|
105764
106508
|
await mkdir3(serverAnalysisDir, { recursive: true });
|
|
105765
106509
|
const result = await Bun.build({
|
|
105766
106510
|
entrypoints: [srcEntry],
|
|
@@ -105773,7 +106517,7 @@ async function analyze(args) {
|
|
|
105773
106517
|
if (result.success && result.outputs.length > 0) {
|
|
105774
106518
|
const output = result.outputs[0];
|
|
105775
106519
|
const code = await output.text();
|
|
105776
|
-
const analysisEntry =
|
|
106520
|
+
const analysisEntry = join16(serverAnalysisDir, "index.js");
|
|
105777
106521
|
await writeFile(analysisEntry, code, "utf-8");
|
|
105778
106522
|
const mapOutput = result.outputs.find((o) => o.path.endsWith(".map"));
|
|
105779
106523
|
if (mapOutput) {
|
|
@@ -105791,7 +106535,7 @@ async function analyze(args) {
|
|
|
105791
106535
|
`));
|
|
105792
106536
|
const installedSizes = await getInstalledPackageSizes(cwd);
|
|
105793
106537
|
if (depTree) {
|
|
105794
|
-
const packageJsonPath =
|
|
106538
|
+
const packageJsonPath = join16(cwd, "package.json");
|
|
105795
106539
|
if (existsSync11(packageJsonPath)) {
|
|
105796
106540
|
try {
|
|
105797
106541
|
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf-8"));
|
|
@@ -105803,7 +106547,7 @@ async function analyze(args) {
|
|
|
105803
106547
|
if (!trackedPkgs.has(pkgName) && installedSizes.has(pkgName)) {
|
|
105804
106548
|
nodeModulesNode.children?.push({
|
|
105805
106549
|
name: pkgName,
|
|
105806
|
-
path:
|
|
106550
|
+
path: join16(cwd, "node_modules", pkgName),
|
|
105807
106551
|
size: installedSizes.get(pkgName) || 0
|
|
105808
106552
|
});
|
|
105809
106553
|
}
|
|
@@ -105834,10 +106578,10 @@ async function analyze(args) {
|
|
|
105834
106578
|
const fullOutput = args.includes("--full");
|
|
105835
106579
|
await printConsoleReport(stats, depTree, mainInfo, browserDepTree, browserInfo, fullOutput);
|
|
105836
106580
|
if (outputHtml || openBrowser) {
|
|
105837
|
-
const htmlPath =
|
|
106581
|
+
const htmlPath = join16(cwd, ".reroute", "analysis.html");
|
|
105838
106582
|
const html2 = await generateHTMLReport(stats, depTree, mainInfo, browserDepTree, browserInfo, initialSearch);
|
|
105839
106583
|
const { mkdir: mkdir3 } = await import("node:fs/promises");
|
|
105840
|
-
await mkdir3(
|
|
106584
|
+
await mkdir3(join16(cwd, ".reroute"), { recursive: true });
|
|
105841
106585
|
await writeFile(htmlPath, html2, "utf-8");
|
|
105842
106586
|
console.log(colorizeLogPrefixAnsi(`[reroute/analyze] HTML report generated: ${relative3(cwd, htmlPath)}
|
|
105843
106587
|
`));
|
|
@@ -105900,8 +106644,8 @@ __export(exports_og, {
|
|
|
105900
106644
|
default: () => og2
|
|
105901
106645
|
});
|
|
105902
106646
|
import { spawn as spawn5 } from "node:child_process";
|
|
105903
|
-
import { readdir as
|
|
105904
|
-
import { join as
|
|
106647
|
+
import { readdir as readdir9 } from "node:fs/promises";
|
|
106648
|
+
import { join as join17 } from "node:path";
|
|
105905
106649
|
function getPortFromConfig(baseUrl) {
|
|
105906
106650
|
if (!baseUrl)
|
|
105907
106651
|
return 3000;
|
|
@@ -105978,10 +106722,10 @@ Error output:`, errorOutput);
|
|
|
105978
106722
|
}
|
|
105979
106723
|
async function scanForOgTemplates(dir, base, routes) {
|
|
105980
106724
|
try {
|
|
105981
|
-
const entries = await
|
|
106725
|
+
const entries = await readdir9(dir, { withFileTypes: true });
|
|
105982
106726
|
for (const entry of entries) {
|
|
105983
|
-
const fullPath =
|
|
105984
|
-
const relativePath =
|
|
106727
|
+
const fullPath = join17(dir, entry.name);
|
|
106728
|
+
const relativePath = join17(base, entry.name);
|
|
105985
106729
|
if (entry.isDirectory()) {
|
|
105986
106730
|
if (entry.name === "content")
|
|
105987
106731
|
continue;
|
|
@@ -105998,13 +106742,13 @@ function findFirstContentFile(contentFiles) {
|
|
|
105998
106742
|
}
|
|
105999
106743
|
async function addContentRoutes(routesPath, routes) {
|
|
106000
106744
|
try {
|
|
106001
|
-
const entries = await
|
|
106745
|
+
const entries = await readdir9(routesPath, { withFileTypes: true });
|
|
106002
106746
|
for (const entry of entries) {
|
|
106003
106747
|
if (!entry.isDirectory())
|
|
106004
106748
|
continue;
|
|
106005
|
-
const contentDir =
|
|
106749
|
+
const contentDir = join17(routesPath, entry.name, "content");
|
|
106006
106750
|
try {
|
|
106007
|
-
const contentFiles = await
|
|
106751
|
+
const contentFiles = await readdir9(contentDir);
|
|
106008
106752
|
if (contentFiles.length === 0)
|
|
106009
106753
|
continue;
|
|
106010
106754
|
const firstFile = findFirstContentFile(contentFiles);
|
|
@@ -106019,7 +106763,7 @@ async function addContentRoutes(routesPath, routes) {
|
|
|
106019
106763
|
async function findRoutesWithOG(cwd) {
|
|
106020
106764
|
const routes = [];
|
|
106021
106765
|
try {
|
|
106022
|
-
const manifestPath =
|
|
106766
|
+
const manifestPath = join17(cwd, ".reroute", "manifest.json");
|
|
106023
106767
|
const manifestFile = Bun.file(manifestPath);
|
|
106024
106768
|
const manifest = await manifestFile.json();
|
|
106025
106769
|
if (manifest.staticRoutes && Array.isArray(manifest.staticRoutes)) {
|
|
@@ -106030,7 +106774,7 @@ async function findRoutesWithOG(cwd) {
|
|
|
106030
106774
|
}
|
|
106031
106775
|
} catch {
|
|
106032
106776
|
console.warn("⚠️ .reroute/manifest.json not found, scanning routes directory...");
|
|
106033
|
-
const routesPath =
|
|
106777
|
+
const routesPath = join17(cwd, ROUTES_DIR2);
|
|
106034
106778
|
await scanForOgTemplates(routesPath, "", routes);
|
|
106035
106779
|
await addContentRoutes(routesPath, routes);
|
|
106036
106780
|
}
|
|
@@ -106282,7 +107026,7 @@ async function getVersionString2() {
|
|
|
106282
107026
|
}
|
|
106283
107027
|
async function getVersion2() {
|
|
106284
107028
|
if (true) {
|
|
106285
|
-
return "0.
|
|
107029
|
+
return "0.46.0";
|
|
106286
107030
|
}
|
|
106287
107031
|
const possiblePaths = [
|
|
106288
107032
|
path3.join(import.meta.dir, "../../../package.json"),
|
|
@@ -106299,10 +107043,10 @@ async function getVersion2() {
|
|
|
106299
107043
|
}
|
|
106300
107044
|
async function getCommit2() {
|
|
106301
107045
|
if (true) {
|
|
106302
|
-
return "
|
|
107046
|
+
return "9116acf";
|
|
106303
107047
|
}
|
|
106304
107048
|
return "dev";
|
|
106305
107049
|
}
|
|
106306
107050
|
main();
|
|
106307
107051
|
|
|
106308
|
-
//# debugId=
|
|
107052
|
+
//# debugId=0B12295AB270224764756E2164756E21
|