boltdocs 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{cache-EHR7SXRU.mjs → cache-GQHF6BXI.mjs} +1 -1
- package/dist/{chunk-GSYECEZY.mjs → chunk-CYBWLFOG.mjs} +5 -1
- package/dist/node/index.js +36 -20
- package/dist/node/index.mjs +34 -22
- package/package.json +1 -1
- package/src/client/app/index.tsx +344 -344
- package/src/client/app/preload.tsx +56 -56
- package/src/client/index.ts +40 -40
- package/src/client/ssr.tsx +51 -51
- package/src/client/theme/components/CodeBlock/CodeBlock.tsx +76 -76
- package/src/client/theme/components/CodeBlock/index.ts +1 -1
- package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +154 -154
- package/src/client/theme/components/PackageManagerTabs/index.ts +1 -1
- package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +64 -64
- package/src/client/theme/components/Playground/Playground.tsx +124 -124
- package/src/client/theme/components/Playground/index.ts +1 -1
- package/src/client/theme/components/Playground/playground.css +168 -168
- package/src/client/theme/components/Video/Video.tsx +84 -84
- package/src/client/theme/components/Video/index.ts +1 -1
- package/src/client/theme/components/Video/video.css +41 -41
- package/src/client/theme/components/mdx/Admonition.tsx +80 -80
- package/src/client/theme/components/mdx/Badge.tsx +31 -31
- package/src/client/theme/components/mdx/Button.tsx +50 -50
- package/src/client/theme/components/mdx/Card.tsx +80 -80
- package/src/client/theme/components/mdx/List.tsx +57 -57
- package/src/client/theme/components/mdx/Tabs.tsx +94 -94
- package/src/client/theme/components/mdx/index.ts +18 -18
- package/src/client/theme/components/mdx/mdx-components.css +424 -424
- package/src/client/theme/icons/bun.tsx +62 -62
- package/src/client/theme/icons/deno.tsx +20 -20
- package/src/client/theme/icons/discord.tsx +12 -12
- package/src/client/theme/icons/github.tsx +15 -15
- package/src/client/theme/icons/npm.tsx +13 -13
- package/src/client/theme/icons/pnpm.tsx +72 -72
- package/src/client/theme/icons/twitter.tsx +12 -12
- package/src/client/theme/styles/markdown.css +343 -343
- package/src/client/theme/styles/variables.css +162 -162
- package/src/client/theme/styles.css +37 -37
- package/src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx +10 -10
- package/src/client/theme/ui/BackgroundGradient/index.ts +1 -1
- package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +68 -68
- package/src/client/theme/ui/Breadcrumbs/index.ts +1 -1
- package/src/client/theme/ui/Footer/footer.css +32 -32
- package/src/client/theme/ui/Head/Head.tsx +69 -69
- package/src/client/theme/ui/Head/index.ts +1 -1
- package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +125 -125
- package/src/client/theme/ui/LanguageSwitcher/index.ts +1 -1
- package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +98 -98
- package/src/client/theme/ui/Layout/Layout.tsx +202 -202
- package/src/client/theme/ui/Layout/base.css +76 -76
- package/src/client/theme/ui/Layout/index.ts +2 -2
- package/src/client/theme/ui/Layout/pagination.css +72 -72
- package/src/client/theme/ui/Layout/responsive.css +36 -36
- package/src/client/theme/ui/Link/Link.tsx +254 -254
- package/src/client/theme/ui/Link/index.ts +2 -2
- package/src/client/theme/ui/Loading/Loading.tsx +10 -10
- package/src/client/theme/ui/Loading/index.ts +1 -1
- package/src/client/theme/ui/Loading/loading.css +30 -30
- package/src/client/theme/ui/Navbar/GithubStars.tsx +27 -27
- package/src/client/theme/ui/Navbar/Navbar.tsx +145 -145
- package/src/client/theme/ui/Navbar/index.ts +2 -2
- package/src/client/theme/ui/Navbar/navbar.css +233 -233
- package/src/client/theme/ui/NotFound/NotFound.tsx +19 -19
- package/src/client/theme/ui/NotFound/index.ts +1 -1
- package/src/client/theme/ui/NotFound/not-found.css +64 -64
- package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +235 -235
- package/src/client/theme/ui/OnThisPage/index.ts +1 -1
- package/src/client/theme/ui/OnThisPage/toc.css +132 -132
- package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +18 -18
- package/src/client/theme/ui/PoweredBy/index.ts +1 -1
- package/src/client/theme/ui/PoweredBy/powered-by.css +76 -76
- package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +199 -199
- package/src/client/theme/ui/SearchDialog/index.ts +1 -1
- package/src/client/theme/ui/SearchDialog/search.css +152 -152
- package/src/client/theme/ui/Sidebar/Sidebar.tsx +204 -204
- package/src/client/theme/ui/Sidebar/index.ts +1 -1
- package/src/client/theme/ui/Sidebar/sidebar.css +236 -236
- package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +69 -69
- package/src/client/theme/ui/ThemeToggle/index.ts +1 -1
- package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +136 -136
- package/src/client/theme/ui/VersionSwitcher/index.ts +1 -1
- package/src/client/types.ts +50 -50
- package/src/client/utils.ts +26 -26
- package/src/node/cache.ts +408 -408
- package/src/node/config.ts +192 -192
- package/src/node/index.ts +21 -21
- package/src/node/mdx.ts +120 -120
- package/src/node/plugin/entry.ts +58 -58
- package/src/node/plugin/html.ts +55 -55
- package/src/node/plugin/index.ts +193 -193
- package/src/node/plugin/types.ts +11 -11
- package/src/node/routes/cache.ts +28 -28
- package/src/node/routes/index.ts +167 -167
- package/src/node/routes/parser.ts +153 -127
- package/src/node/routes/sorter.ts +42 -42
- package/src/node/routes/types.ts +49 -49
- package/src/node/ssg/index.ts +114 -114
- package/src/node/ssg/meta.ts +33 -34
- package/src/node/ssg/options.ts +13 -13
- package/src/node/ssg/sitemap.ts +55 -54
- package/src/node/utils.ts +145 -134
- package/tsconfig.json +20 -20
- package/tsup.config.ts +22 -22
package/src/node/routes/cache.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { FileCache } from "../cache";
|
|
2
|
-
import { ParsedDocFile } from "./types";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Persistent cache for parsed documentation files.
|
|
6
|
-
* Saves data to `.boltdocs/routes.json`.
|
|
7
|
-
*/
|
|
8
|
-
const docCache = new FileCache<ParsedDocFile>({ name: "routes" });
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Invalidate all cached routes.
|
|
12
|
-
* Typically called when a file is added or deleted, requiring a complete route rebuild.
|
|
13
|
-
*/
|
|
14
|
-
export function invalidateRouteCache(): void {
|
|
15
|
-
docCache.invalidateAll();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Invalidate a specific file from cache.
|
|
20
|
-
* Called when a specific file is modified (changed).
|
|
21
|
-
*
|
|
22
|
-
* @param filePath - The absolute path of the file to invalidate
|
|
23
|
-
*/
|
|
24
|
-
export function invalidateFile(filePath: string): void {
|
|
25
|
-
docCache.invalidate(filePath);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { docCache };
|
|
1
|
+
import { FileCache } from "../cache";
|
|
2
|
+
import { ParsedDocFile } from "./types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Persistent cache for parsed documentation files.
|
|
6
|
+
* Saves data to `.boltdocs/routes.json`.
|
|
7
|
+
*/
|
|
8
|
+
const docCache = new FileCache<ParsedDocFile>({ name: "routes" });
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Invalidate all cached routes.
|
|
12
|
+
* Typically called when a file is added or deleted, requiring a complete route rebuild.
|
|
13
|
+
*/
|
|
14
|
+
export function invalidateRouteCache(): void {
|
|
15
|
+
docCache.invalidateAll();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Invalidate a specific file from cache.
|
|
20
|
+
* Called when a specific file is modified (changed).
|
|
21
|
+
*
|
|
22
|
+
* @param filePath - The absolute path of the file to invalidate
|
|
23
|
+
*/
|
|
24
|
+
export function invalidateFile(filePath: string): void {
|
|
25
|
+
docCache.invalidate(filePath);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { docCache };
|
package/src/node/routes/index.ts
CHANGED
|
@@ -1,167 +1,167 @@
|
|
|
1
|
-
import fastGlob from "fast-glob";
|
|
2
|
-
import { BoltdocsConfig } from "../config";
|
|
3
|
-
import { capitalize } from "../utils";
|
|
4
|
-
|
|
5
|
-
import { RouteMeta, ParsedDocFile } from "./types";
|
|
6
|
-
import { docCache, invalidateRouteCache, invalidateFile } from "./cache";
|
|
7
|
-
import { parseDocFile } from "./parser";
|
|
8
|
-
import { sortRoutes } from "./sorter";
|
|
9
|
-
|
|
10
|
-
// Re-export public API
|
|
11
|
-
export type { RouteMeta };
|
|
12
|
-
export { invalidateRouteCache, invalidateFile };
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Generates the entire route map for the documentation site.
|
|
16
|
-
* This reads all `.md` and `.mdx` files in the `docsDir`, parses them (using cache),
|
|
17
|
-
* infers group hierarchies based on directory structure and `index.md` files,
|
|
18
|
-
* and returns a sorted array of RouteMeta objects intended for the client.
|
|
19
|
-
*
|
|
20
|
-
* @param docsDir - The root directory containing markdown files
|
|
21
|
-
* @param config - Optional configuration for i18n and versioning
|
|
22
|
-
* @param basePath - The base URL path to prefix to generated routes (e.g., '/docs')
|
|
23
|
-
* @returns A promise that resolves to the final list of RouteMeta objects
|
|
24
|
-
*/
|
|
25
|
-
export async function generateRoutes(
|
|
26
|
-
docsDir: string,
|
|
27
|
-
config?: BoltdocsConfig,
|
|
28
|
-
basePath: string = "/docs",
|
|
29
|
-
): Promise<RouteMeta[]> {
|
|
30
|
-
// Load persistent cache on first call
|
|
31
|
-
docCache.load();
|
|
32
|
-
|
|
33
|
-
const files = await fastGlob(["**/*.md", "**/*.mdx"], {
|
|
34
|
-
cwd: docsDir,
|
|
35
|
-
absolute: true,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Prune cache entries for deleted files
|
|
39
|
-
docCache.pruneStale(new Set(files));
|
|
40
|
-
|
|
41
|
-
// Invalidate all caches if config changes drastically (e.g. i18n enabled)
|
|
42
|
-
if (config?.i18n) {
|
|
43
|
-
docCache.invalidateAll();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Parse files in parallel using Promise.all for increased efficiency
|
|
47
|
-
let cacheHits = 0;
|
|
48
|
-
const parsed: ParsedDocFile[] = await Promise.all(
|
|
49
|
-
files.map(async (file) => {
|
|
50
|
-
const cached = docCache.get(file);
|
|
51
|
-
if (cached) {
|
|
52
|
-
cacheHits++;
|
|
53
|
-
return cached;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const result = parseDocFile(file, docsDir, basePath, config);
|
|
57
|
-
docCache.set(file, result);
|
|
58
|
-
return result;
|
|
59
|
-
}),
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
if (files.length > 0) {
|
|
63
|
-
console.log(
|
|
64
|
-
`[boltdocs] Routes generated: ${files.length} files (${cacheHits} from cache, ${files.length - cacheHits} parsed)`,
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Save cache after batch processing
|
|
69
|
-
docCache.save();
|
|
70
|
-
|
|
71
|
-
// Collect group metadata from directory names and index files
|
|
72
|
-
const groupMeta = new Map<string, { title: string; position?: number }>();
|
|
73
|
-
for (const p of parsed) {
|
|
74
|
-
if (p.relativeDir) {
|
|
75
|
-
if (!groupMeta.has(p.relativeDir)) {
|
|
76
|
-
groupMeta.set(p.relativeDir, {
|
|
77
|
-
title: capitalize(p.relativeDir),
|
|
78
|
-
position: p.inferredGroupPosition,
|
|
79
|
-
});
|
|
80
|
-
} else {
|
|
81
|
-
const entry = groupMeta.get(p.relativeDir)!;
|
|
82
|
-
if (
|
|
83
|
-
entry.position === undefined &&
|
|
84
|
-
p.inferredGroupPosition !== undefined
|
|
85
|
-
) {
|
|
86
|
-
entry.position = p.inferredGroupPosition;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (p.isGroupIndex && p.relativeDir && p.groupMeta) {
|
|
92
|
-
const entry = groupMeta.get(p.relativeDir)!;
|
|
93
|
-
entry.title = p.groupMeta.title;
|
|
94
|
-
if (p.groupMeta.position !== undefined) {
|
|
95
|
-
entry.position = p.groupMeta.position;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Build final routes with group info
|
|
101
|
-
const routes: RouteMeta[] = parsed.map((p) => {
|
|
102
|
-
const dir = p.relativeDir;
|
|
103
|
-
const meta = dir ? groupMeta.get(dir) : undefined;
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
...p.route,
|
|
107
|
-
group: dir,
|
|
108
|
-
groupTitle: meta?.title || (dir ? capitalize(dir) : undefined),
|
|
109
|
-
groupPosition: meta?.position,
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Add fallbacks if i18n is enabled
|
|
114
|
-
if (config?.i18n) {
|
|
115
|
-
const defaultLocale = config.i18n.defaultLocale;
|
|
116
|
-
const allLocales = Object.keys(config.i18n.locales);
|
|
117
|
-
|
|
118
|
-
const fallbackRoutes: RouteMeta[] = [];
|
|
119
|
-
const defaultRoutes = routes.filter(
|
|
120
|
-
(r) => (r.locale || defaultLocale) === defaultLocale,
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
for (const locale of allLocales) {
|
|
124
|
-
if (locale === defaultLocale) continue;
|
|
125
|
-
|
|
126
|
-
const localeRoutePaths = new Set(
|
|
127
|
-
routes.filter((r) => r.locale === locale).map((r) => r.path),
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
for (const defRoute of defaultRoutes) {
|
|
131
|
-
let prefix = basePath;
|
|
132
|
-
if (defRoute.version) {
|
|
133
|
-
prefix += "/" + defRoute.version;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
let pathAfterVersion = defRoute.path.substring(prefix.length);
|
|
137
|
-
|
|
138
|
-
if (pathAfterVersion.startsWith("/" + defaultLocale + "/")) {
|
|
139
|
-
pathAfterVersion = pathAfterVersion.substring(
|
|
140
|
-
defaultLocale.length + 1,
|
|
141
|
-
);
|
|
142
|
-
} else if (pathAfterVersion === "/" + defaultLocale) {
|
|
143
|
-
pathAfterVersion = "/";
|
|
144
|
-
}
|
|
145
|
-
const targetPath =
|
|
146
|
-
prefix +
|
|
147
|
-
"/" +
|
|
148
|
-
locale +
|
|
149
|
-
(pathAfterVersion === "/" || pathAfterVersion === ""
|
|
150
|
-
? ""
|
|
151
|
-
: pathAfterVersion);
|
|
152
|
-
|
|
153
|
-
if (!localeRoutePaths.has(targetPath)) {
|
|
154
|
-
fallbackRoutes.push({
|
|
155
|
-
...defRoute,
|
|
156
|
-
path: targetPath,
|
|
157
|
-
locale: locale,
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return sortRoutes([...routes, ...fallbackRoutes]);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return sortRoutes(routes);
|
|
167
|
-
}
|
|
1
|
+
import fastGlob from "fast-glob";
|
|
2
|
+
import { BoltdocsConfig } from "../config";
|
|
3
|
+
import { capitalize } from "../utils";
|
|
4
|
+
|
|
5
|
+
import { RouteMeta, ParsedDocFile } from "./types";
|
|
6
|
+
import { docCache, invalidateRouteCache, invalidateFile } from "./cache";
|
|
7
|
+
import { parseDocFile } from "./parser";
|
|
8
|
+
import { sortRoutes } from "./sorter";
|
|
9
|
+
|
|
10
|
+
// Re-export public API
|
|
11
|
+
export type { RouteMeta };
|
|
12
|
+
export { invalidateRouteCache, invalidateFile };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generates the entire route map for the documentation site.
|
|
16
|
+
* This reads all `.md` and `.mdx` files in the `docsDir`, parses them (using cache),
|
|
17
|
+
* infers group hierarchies based on directory structure and `index.md` files,
|
|
18
|
+
* and returns a sorted array of RouteMeta objects intended for the client.
|
|
19
|
+
*
|
|
20
|
+
* @param docsDir - The root directory containing markdown files
|
|
21
|
+
* @param config - Optional configuration for i18n and versioning
|
|
22
|
+
* @param basePath - The base URL path to prefix to generated routes (e.g., '/docs')
|
|
23
|
+
* @returns A promise that resolves to the final list of RouteMeta objects
|
|
24
|
+
*/
|
|
25
|
+
export async function generateRoutes(
|
|
26
|
+
docsDir: string,
|
|
27
|
+
config?: BoltdocsConfig,
|
|
28
|
+
basePath: string = "/docs",
|
|
29
|
+
): Promise<RouteMeta[]> {
|
|
30
|
+
// Load persistent cache on first call
|
|
31
|
+
docCache.load();
|
|
32
|
+
|
|
33
|
+
const files = await fastGlob(["**/*.md", "**/*.mdx"], {
|
|
34
|
+
cwd: docsDir,
|
|
35
|
+
absolute: true,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Prune cache entries for deleted files
|
|
39
|
+
docCache.pruneStale(new Set(files));
|
|
40
|
+
|
|
41
|
+
// Invalidate all caches if config changes drastically (e.g. i18n enabled)
|
|
42
|
+
if (config?.i18n) {
|
|
43
|
+
docCache.invalidateAll();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Parse files in parallel using Promise.all for increased efficiency
|
|
47
|
+
let cacheHits = 0;
|
|
48
|
+
const parsed: ParsedDocFile[] = await Promise.all(
|
|
49
|
+
files.map(async (file) => {
|
|
50
|
+
const cached = docCache.get(file);
|
|
51
|
+
if (cached) {
|
|
52
|
+
cacheHits++;
|
|
53
|
+
return cached;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const result = parseDocFile(file, docsDir, basePath, config);
|
|
57
|
+
docCache.set(file, result);
|
|
58
|
+
return result;
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (files.length > 0) {
|
|
63
|
+
console.log(
|
|
64
|
+
`[boltdocs] Routes generated: ${files.length} files (${cacheHits} from cache, ${files.length - cacheHits} parsed)`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Save cache after batch processing
|
|
69
|
+
docCache.save();
|
|
70
|
+
|
|
71
|
+
// Collect group metadata from directory names and index files
|
|
72
|
+
const groupMeta = new Map<string, { title: string; position?: number }>();
|
|
73
|
+
for (const p of parsed) {
|
|
74
|
+
if (p.relativeDir) {
|
|
75
|
+
if (!groupMeta.has(p.relativeDir)) {
|
|
76
|
+
groupMeta.set(p.relativeDir, {
|
|
77
|
+
title: capitalize(p.relativeDir),
|
|
78
|
+
position: p.inferredGroupPosition,
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
const entry = groupMeta.get(p.relativeDir)!;
|
|
82
|
+
if (
|
|
83
|
+
entry.position === undefined &&
|
|
84
|
+
p.inferredGroupPosition !== undefined
|
|
85
|
+
) {
|
|
86
|
+
entry.position = p.inferredGroupPosition;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (p.isGroupIndex && p.relativeDir && p.groupMeta) {
|
|
92
|
+
const entry = groupMeta.get(p.relativeDir)!;
|
|
93
|
+
entry.title = p.groupMeta.title;
|
|
94
|
+
if (p.groupMeta.position !== undefined) {
|
|
95
|
+
entry.position = p.groupMeta.position;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Build final routes with group info
|
|
101
|
+
const routes: RouteMeta[] = parsed.map((p) => {
|
|
102
|
+
const dir = p.relativeDir;
|
|
103
|
+
const meta = dir ? groupMeta.get(dir) : undefined;
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
...p.route,
|
|
107
|
+
group: dir,
|
|
108
|
+
groupTitle: meta?.title || (dir ? capitalize(dir) : undefined),
|
|
109
|
+
groupPosition: meta?.position,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Add fallbacks if i18n is enabled
|
|
114
|
+
if (config?.i18n) {
|
|
115
|
+
const defaultLocale = config.i18n.defaultLocale;
|
|
116
|
+
const allLocales = Object.keys(config.i18n.locales);
|
|
117
|
+
|
|
118
|
+
const fallbackRoutes: RouteMeta[] = [];
|
|
119
|
+
const defaultRoutes = routes.filter(
|
|
120
|
+
(r) => (r.locale || defaultLocale) === defaultLocale,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
for (const locale of allLocales) {
|
|
124
|
+
if (locale === defaultLocale) continue;
|
|
125
|
+
|
|
126
|
+
const localeRoutePaths = new Set(
|
|
127
|
+
routes.filter((r) => r.locale === locale).map((r) => r.path),
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
for (const defRoute of defaultRoutes) {
|
|
131
|
+
let prefix = basePath;
|
|
132
|
+
if (defRoute.version) {
|
|
133
|
+
prefix += "/" + defRoute.version;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let pathAfterVersion = defRoute.path.substring(prefix.length);
|
|
137
|
+
|
|
138
|
+
if (pathAfterVersion.startsWith("/" + defaultLocale + "/")) {
|
|
139
|
+
pathAfterVersion = pathAfterVersion.substring(
|
|
140
|
+
defaultLocale.length + 1,
|
|
141
|
+
);
|
|
142
|
+
} else if (pathAfterVersion === "/" + defaultLocale) {
|
|
143
|
+
pathAfterVersion = "/";
|
|
144
|
+
}
|
|
145
|
+
const targetPath =
|
|
146
|
+
prefix +
|
|
147
|
+
"/" +
|
|
148
|
+
locale +
|
|
149
|
+
(pathAfterVersion === "/" || pathAfterVersion === ""
|
|
150
|
+
? ""
|
|
151
|
+
: pathAfterVersion);
|
|
152
|
+
|
|
153
|
+
if (!localeRoutePaths.has(targetPath)) {
|
|
154
|
+
fallbackRoutes.push({
|
|
155
|
+
...defRoute,
|
|
156
|
+
path: targetPath,
|
|
157
|
+
locale: locale,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return sortRoutes([...routes, ...fallbackRoutes]);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return sortRoutes(routes);
|
|
167
|
+
}
|