boltdocs 2.7.11 → 2.8.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 +2 -2
- package/dist/banner-3N4Jd_L9.d.ts +100 -0
- package/dist/banner-MynZD_Ox.d.cts +100 -0
- package/dist/cache-BMUyNiiA.mjs +6 -0
- package/dist/cache-CKm45d2w.cjs +6 -0
- package/dist/client/index.cjs +782 -443
- package/dist/client/index.d.cts +86 -110
- package/dist/client/index.d.ts +87 -111
- package/dist/client/index.js +773 -439
- package/dist/client/mdx.cjs +8 -3
- package/dist/client/mdx.d.cts +39 -93
- package/dist/client/mdx.d.ts +38 -93
- package/dist/client/mdx.js +3 -3
- package/dist/client/primitives.cjs +7 -7
- package/dist/client/primitives.d.cts +411 -347
- package/dist/client/primitives.d.ts +411 -347
- package/dist/client/primitives.js +4 -4
- package/dist/{docs-layout-BXHV0xw_.cjs → docs-layout-CwCq42Zt.cjs} +95 -178
- package/dist/{docs-layout-DwFndmj5.js → docs-layout-Dn6S5g59.js} +99 -163
- package/dist/doctor-BArviV8X.cjs +28 -0
- package/dist/doctor-CgLA7_Uv.mjs +28 -0
- package/dist/{doctor-CrytFkqW.cjs → doctor-DyNUVe96.cjs} +1 -1
- package/dist/{routes-DP1vmWRj.cjs → doctor-aN_leTbh.mjs} +1 -1
- package/dist/{generator-ClVanhvi.mjs → generator-BHCrLU6h.mjs} +2 -2
- package/dist/{generator-CHqxiQhF.cjs → generator-CC2yHzhZ.cjs} +2 -2
- package/dist/{icons-dev-3cZMyt8r.cjs → icons-dev-DvJ-hh9x.cjs} +116 -111
- package/dist/{icons-dev-Df8OQ481.js → icons-dev-Oju24Wjp.js} +120 -114
- package/dist/{image-DtrI2cw3.cjs → image-Ch4-GxdO.cjs} +13 -13
- package/dist/{image-jxPb-2iV.js → image-Do8V9PCW.js} +13 -13
- package/dist/{mdx-UTTLFWJq.js → mdx-D3A2_l7P.js} +106 -80
- package/dist/{mdx-BdWkJTeB.cjs → mdx-PLhhPJRS.cjs} +104 -96
- package/dist/node/cli-entry.cjs +3 -1
- package/dist/node/cli-entry.mjs +3 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +258 -152
- package/dist/node/index.d.mts +258 -150
- package/dist/node/index.mjs +1 -1
- package/dist/node/routes/worker.cjs +1 -1
- package/dist/node/routes/worker.mjs +1 -1
- package/dist/node-BmlP0eBP.cjs +159 -0
- package/dist/node-Y8_4ayje.mjs +159 -0
- package/dist/package-2nFy_NsW.cjs +6 -0
- package/dist/{package-K0zsjGIz.mjs → package-DAbtltXX.mjs} +1 -1
- package/dist/parser-B7-6PyQz.cjs +6 -0
- package/dist/{parser-Aq8LoH-0.cjs → parser-BzB-zCkF.cjs} +1 -1
- package/dist/parser-WGZdWs0X.mjs +6 -0
- package/dist/routes-BDDSxAl0.mjs +6 -0
- package/dist/routes-DJNJ-rTt.cjs +6 -0
- package/dist/routes-DiYC4nD2.cjs +6 -0
- package/dist/routes-_Bb2f4eI.mjs +6 -0
- package/dist/{search-dialog-C7xuvyNk.cjs → search-dialog-BXVoecTx.cjs} +175 -78
- package/dist/{search-dialog-BwkDuI9R.cjs → search-dialog-BYhOov4S.cjs} +118 -7
- package/dist/{search-dialog-D-DDN7zJ.js → search-dialog-C09riYmx.js} +113 -8
- package/dist/{search-dialog-CIQg6k8c.cjs → search-dialog-CUeAfy-8.cjs} +1 -1
- package/dist/{search-dialog-BNF10tDl.js → search-dialog-D8gLkhUV.js} +158 -80
- package/dist/{search-dialog-BHuIiUC6.js → search-dialog-DHc_8FFX.js} +1 -1
- package/dist/{sidebar-CyZS9YOm.d.ts → sidebar-DNq4_ZAa.d.ts} +117 -51
- package/dist/{sidebar-CcBkrm06.d.cts → sidebar-Dlkgbxs6.d.cts} +117 -51
- package/dist/utils-BYITg7T5.mjs +7 -0
- package/dist/utils-Cjmx1hhk.cjs +7 -0
- package/dist/worker-pool-CtqklOXq.cjs +6 -0
- package/dist/worker-pool-k0DY6k8T.mjs +6 -0
- package/package.json +3 -3
- package/src/shared/config-utils.ts +4 -0
- package/src/shared/types.ts +52 -6
- package/dist/cache-Ba-DZQNH.cjs +0 -6
- package/dist/cache-BuMZ58L5.mjs +0 -6
- package/dist/cards-BakZPTz9.d.ts +0 -30
- package/dist/cards-CQn9mXZS.d.cts +0 -30
- package/dist/doctor-Be7Ly1oM.mjs +0 -21
- package/dist/doctor-jMxWZyLJ.cjs +0 -21
- package/dist/node-BSM4qcDK.cjs +0 -111
- package/dist/node-BspZN3R2.mjs +0 -111
- package/dist/package-DIIrjuWI.cjs +0 -6
- package/dist/parser-CdNbqN5y.cjs +0 -6
- package/dist/parser-nE792MLO.mjs +0 -6
- package/dist/rolldown-runtime-fkIsjY3S.mjs +0 -6
- package/dist/routes-2k3tbUmC.cjs +0 -6
- package/dist/routes-CpxZIsMM.mjs +0 -6
- package/dist/utils-CG65J0Sc.mjs +0 -7
- package/dist/utils-CKunkU96.cjs +0 -7
- package/dist/worker-pool-CGn7DrLb.mjs +0 -6
- package/dist/worker-pool-Crbqgw5R.cjs +0 -6
- /package/dist/{meta-loader-CWg2gnbY.mjs → meta-loader-DzwDFtdT.mjs} +0 -0
package/dist/client/index.js
CHANGED
|
@@ -3,51 +3,321 @@
|
|
|
3
3
|
* Copyright (c) 2026 Jesus Alcala
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
import { $ as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { n as
|
|
11
|
-
import {
|
|
6
|
+
import { $ as ConfigContext, B as Languages, C as RoutesProvider, D as Check, E as ArrowLeft, G as Moon, M as Copy, O as ChevronDown, P as ExternalLink, Q as icons_exports, R as Home, S as normalizePath, U as Menu, W as Monitor, X as TextAlignStart, Y as Sun, Z as X, _ as Link$1, b as useLocalizedTo, et as useConfig, j as CircleHelp, nt as useBoltdocsContext, q as Pencil, s as Github, tt as BoltdocsProvider, x as useRoutes, y as cn } from "../icons-dev-Oju24Wjp.js";
|
|
7
|
+
import { c as ThemeProvider, l as useTheme } from "../image-Do8V9PCW.js";
|
|
8
|
+
import { n as copyToClipboard, t as mdx_components_default } from "../mdx-D3A2_l7P.js";
|
|
9
|
+
import { A as useUI, D as ButtonGroup, O as Breadcrumbs$2, T as Menu$1, _ as OnThisPage$1, h as PageNav$1, i as Sidebar$1, k as UIProvider, m as useSidebar, n as useSearchHighlight, r as useLocation, t as DocsLayout$1, w as Tabs$1 } from "../docs-layout-Dn6S5g59.js";
|
|
10
|
+
import { a as Button$1, n as Navbar$1, r as ErrorBoundary$1 } from "../search-dialog-D8gLkhUV.js";
|
|
11
|
+
import { n as useSearch, r as InternalErrorBoundary, t as SearchDialog } from "../search-dialog-C09riYmx.js";
|
|
12
12
|
import { ViteReactSSG } from "@bdocs/ssg";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { Suspense, createContext, isValidElement, lazy, use, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
14
|
+
import { Link, Outlet, useLoaderData, useLocation as useLocation$1, useMatches, useNavigate } from "react-router-dom";
|
|
15
15
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
import { Button } from "react-aria-components";
|
|
17
|
-
import virtualIcons from "virtual:boltdocs-icons";
|
|
18
16
|
import * as ReactHelmetAsync from "react-helmet-async";
|
|
17
|
+
import { Button } from "react-aria-components";
|
|
19
18
|
import virtualCustomComponents from "virtual:boltdocs-mdx-components";
|
|
19
|
+
import virtualIcons from "virtual:boltdocs-icons";
|
|
20
20
|
import UserLayout from "virtual:boltdocs-layout";
|
|
21
21
|
|
|
22
22
|
//#region src/client/app/mdx-components-context.tsx
|
|
23
23
|
const MDX_COMPONENTS_CONTEXT_SYMBOL = Symbol.for("__BDOCS_MDX_COMPONENTS_CONTEXT__");
|
|
24
|
-
const
|
|
25
|
-
|
|
24
|
+
const registry = globalThis;
|
|
25
|
+
if (!registry[MDX_COMPONENTS_CONTEXT_SYMBOL]) registry[MDX_COMPONENTS_CONTEXT_SYMBOL] = createContext({});
|
|
26
|
+
const MdxComponentsContext = registry[MDX_COMPONENTS_CONTEXT_SYMBOL];
|
|
26
27
|
function useMdxComponents() {
|
|
27
|
-
|
|
28
|
-
if ((!context || Object.keys(context).length === 0) && globalThis[MDX_COMPONENTS_INSTANCE_SYMBOL]) return globalThis[MDX_COMPONENTS_INSTANCE_SYMBOL];
|
|
29
|
-
return context;
|
|
28
|
+
return use(MdxComponentsContext);
|
|
30
29
|
}
|
|
31
30
|
function MdxComponentsProvider({ components, children }) {
|
|
32
31
|
const processedComponents = useMemo(() => {
|
|
33
32
|
const processed = {};
|
|
34
33
|
const frontmatter = {};
|
|
34
|
+
let hasFrontmatter = false;
|
|
35
35
|
Object.entries(components).forEach(([key, value]) => {
|
|
36
36
|
if (key.startsWith("Frontmatter_")) {
|
|
37
37
|
const cleanKey = key.slice(12);
|
|
38
38
|
frontmatter[cleanKey] = value;
|
|
39
|
+
hasFrontmatter = true;
|
|
39
40
|
} else processed[key] = value;
|
|
40
41
|
});
|
|
41
|
-
processed.Frontmatter = frontmatter;
|
|
42
|
+
if (hasFrontmatter) processed.Frontmatter = frontmatter;
|
|
42
43
|
return processed;
|
|
43
44
|
}, [components]);
|
|
44
|
-
if (typeof globalThis !== "undefined") globalThis[MDX_COMPONENTS_INSTANCE_SYMBOL] = processedComponents;
|
|
45
45
|
return /* @__PURE__ */ jsx(MdxComponentsContext.Provider, {
|
|
46
46
|
value: processedComponents,
|
|
47
47
|
children
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/client/app/helmet-compat.tsx
|
|
53
|
+
const mod = ReactHelmetAsync;
|
|
54
|
+
/**
|
|
55
|
+
* The `<Helmet>` component, resolved across CJS/ESM module shapes.
|
|
56
|
+
* Falls back to a transparent fragment wrapper if the module cannot be resolved.
|
|
57
|
+
*/
|
|
58
|
+
const Helmet = mod.Helmet || mod.default?.Helmet || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
59
|
+
/**
|
|
60
|
+
* The `<HelmetProvider>` component, resolved across CJS/ESM module shapes.
|
|
61
|
+
* Falls back to a transparent fragment wrapper if the module cannot be resolved.
|
|
62
|
+
*/
|
|
63
|
+
const HelmetProvider = mod.HelmetProvider || mod.default?.HelmetProvider || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/client/app/scroll-handler.tsx
|
|
67
|
+
/**
|
|
68
|
+
* Handles scroll restoration and hash scrolling on navigation.
|
|
69
|
+
* It ensures the page scrolls to top on pathname changes,
|
|
70
|
+
* or specifically to an anchor element if a hash is present.
|
|
71
|
+
*/
|
|
72
|
+
function ScrollHandler() {
|
|
73
|
+
const { pathname, hash } = useLocation$1();
|
|
74
|
+
const handleScroll = (behavior = "auto") => {
|
|
75
|
+
const container = document.querySelector(".boltdocs-content") || window;
|
|
76
|
+
const getScrollTop = () => {
|
|
77
|
+
if (container === window) return window.scrollY;
|
|
78
|
+
return container.scrollTop;
|
|
79
|
+
};
|
|
80
|
+
const scrollTo = (top, scrollBehavior) => {
|
|
81
|
+
if (container === window) window.scrollTo({
|
|
82
|
+
top,
|
|
83
|
+
behavior: scrollBehavior
|
|
84
|
+
});
|
|
85
|
+
else container.scrollTo({
|
|
86
|
+
top,
|
|
87
|
+
behavior: scrollBehavior
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
if (hash) {
|
|
91
|
+
const id = hash.replace("#", "");
|
|
92
|
+
const element = document.getElementById(id);
|
|
93
|
+
if (element) {
|
|
94
|
+
const offset = 80;
|
|
95
|
+
const containerTop = container === window ? 0 : container.getBoundingClientRect().top;
|
|
96
|
+
scrollTo(element.getBoundingClientRect().top - containerTop - offset + getScrollTop(), behavior);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
scrollTo(0, behavior);
|
|
101
|
+
return false;
|
|
102
|
+
};
|
|
103
|
+
useLayoutEffect(() => {
|
|
104
|
+
handleScroll("auto");
|
|
105
|
+
}, [pathname, hash]);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
handleScroll("auto");
|
|
108
|
+
const rafId = requestAnimationFrame(() => {
|
|
109
|
+
handleScroll("auto");
|
|
110
|
+
window.dispatchEvent(new Event("resize"));
|
|
111
|
+
});
|
|
112
|
+
return () => cancelAnimationFrame(rafId);
|
|
113
|
+
}, [pathname, hash]);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/client/components/ui-base/not-found.tsx
|
|
119
|
+
function NotFound() {
|
|
120
|
+
return /* @__PURE__ */ jsx("div", {
|
|
121
|
+
className: "flex items-center justify-center min-h-[65vh] text-center px-4",
|
|
122
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
123
|
+
className: "space-y-6 max-w-md mx-auto p-8 border border-subtle bg-surface rounded-2xl shadow-xs",
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ jsx("span", {
|
|
126
|
+
className: "block text-7xl font-extrabold tracking-tight text-primary-500",
|
|
127
|
+
children: "404"
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ jsxs("div", {
|
|
130
|
+
className: "space-y-2",
|
|
131
|
+
children: [/* @__PURE__ */ jsx("h1", {
|
|
132
|
+
className: "text-xl font-bold text-body",
|
|
133
|
+
children: "Page Not Found"
|
|
134
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
135
|
+
className: "text-sm text-muted leading-relaxed",
|
|
136
|
+
children: "The page you're looking for doesn't exist or has been moved."
|
|
137
|
+
})]
|
|
138
|
+
}),
|
|
139
|
+
/* @__PURE__ */ jsxs(Link$1, {
|
|
140
|
+
href: "/",
|
|
141
|
+
className: "inline-flex items-center gap-2 rounded-xl border border-subtle bg-main px-6 py-2.5 text-xs font-semibold text-body hover:bg-primary-50/50 hover:border-primary-500/50 transition-all duration-300 outline-none select-none",
|
|
142
|
+
children: [/* @__PURE__ */ jsx(ArrowLeft, { size: 14 }), " Go to Home"]
|
|
143
|
+
})
|
|
144
|
+
]
|
|
145
|
+
})
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/client/app/mdx-component.tsx
|
|
151
|
+
const mdxComponentsDefault = {
|
|
152
|
+
...mdx_components_default,
|
|
153
|
+
NotFound,
|
|
154
|
+
"404": NotFound
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/client/ssg/boltdocs-shell.tsx
|
|
159
|
+
/**
|
|
160
|
+
* Updates the HTML lang and dir attributes based on the current locale configuration.
|
|
161
|
+
*/
|
|
162
|
+
function I18nUpdater({ config }) {
|
|
163
|
+
const { currentLocale } = useBoltdocsContext();
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (!config.i18n || typeof document === "undefined") return;
|
|
166
|
+
const locale = currentLocale || config.i18n.defaultLocale;
|
|
167
|
+
const localeConfig = config.i18n.localeConfigs?.[locale];
|
|
168
|
+
document.documentElement.lang = localeConfig?.htmlLang || locale || "en";
|
|
169
|
+
document.documentElement.dir = localeConfig?.direction || "ltr";
|
|
170
|
+
}, [currentLocale, config.i18n]);
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
function StoreSync({ config, routeMap }) {
|
|
174
|
+
const location = useLocation$1();
|
|
175
|
+
const { setLocale, setVersion } = useBoltdocsContext();
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
const currentPath = normalizePath(location.pathname);
|
|
178
|
+
const matchedRoute = routeMap.get(currentPath);
|
|
179
|
+
if (matchedRoute) {
|
|
180
|
+
if (config.i18n) setLocale(matchedRoute.locale || config.i18n.defaultLocale);
|
|
181
|
+
if (config.versions) setVersion(matchedRoute.version || config.versions.defaultVersion);
|
|
182
|
+
}
|
|
183
|
+
}, [
|
|
184
|
+
location.pathname,
|
|
185
|
+
config,
|
|
186
|
+
routeMap,
|
|
187
|
+
setLocale,
|
|
188
|
+
setVersion
|
|
189
|
+
]);
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
function BoltdocsShell({ config, routes, components = {} }) {
|
|
193
|
+
const allComponents = useMemo(() => ({
|
|
194
|
+
...mdxComponentsDefault,
|
|
195
|
+
...virtualCustomComponents,
|
|
196
|
+
...components
|
|
197
|
+
}), [components]);
|
|
198
|
+
const { pathname } = useLocation$1();
|
|
199
|
+
const currentPath = useMemo(() => normalizePath(pathname || "/"), [pathname]);
|
|
200
|
+
const routeMap = useMemo(() => {
|
|
201
|
+
const map = /* @__PURE__ */ new Map();
|
|
202
|
+
for (const r of routes) {
|
|
203
|
+
const key = normalizePath(r.path === "" ? "/" : r.path);
|
|
204
|
+
map.set(key, r);
|
|
205
|
+
}
|
|
206
|
+
return map;
|
|
207
|
+
}, [routes]);
|
|
208
|
+
const initialData = useMemo(() => {
|
|
209
|
+
const matched = routeMap.get(currentPath);
|
|
210
|
+
let initLocale;
|
|
211
|
+
let initVersion;
|
|
212
|
+
if (matched) {
|
|
213
|
+
if (config.i18n) initLocale = matched.locale || config.i18n.defaultLocale;
|
|
214
|
+
if (config.versions) initVersion = matched.version || config.versions.defaultVersion;
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
initLocale,
|
|
218
|
+
initVersion
|
|
219
|
+
};
|
|
220
|
+
}, [
|
|
221
|
+
currentPath,
|
|
222
|
+
config,
|
|
223
|
+
routeMap
|
|
224
|
+
]);
|
|
225
|
+
return /* @__PURE__ */ jsx(HelmetProvider, { children: /* @__PURE__ */ jsx(RoutesProvider, {
|
|
226
|
+
routes,
|
|
227
|
+
children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(UIProvider, { children: /* @__PURE__ */ jsx(MdxComponentsProvider, {
|
|
228
|
+
components: allComponents,
|
|
229
|
+
children: /* @__PURE__ */ jsxs(ConfigContext.Provider, {
|
|
230
|
+
value: config,
|
|
231
|
+
children: [/* @__PURE__ */ jsx(ScrollHandler, {}), /* @__PURE__ */ jsxs(BoltdocsProvider, {
|
|
232
|
+
initialLocale: initialData.initLocale,
|
|
233
|
+
initialVersion: initialData.initVersion,
|
|
234
|
+
children: [
|
|
235
|
+
/* @__PURE__ */ jsx(StoreSync, {
|
|
236
|
+
config,
|
|
237
|
+
routeMap
|
|
238
|
+
}),
|
|
239
|
+
/* @__PURE__ */ jsx(I18nUpdater, { config }),
|
|
240
|
+
/* @__PURE__ */ jsx(InternalErrorBoundary, { children: /* @__PURE__ */ jsx(Outlet, {}) })
|
|
241
|
+
]
|
|
242
|
+
})]
|
|
243
|
+
})
|
|
244
|
+
}) }) })
|
|
245
|
+
}) });
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
//#endregion
|
|
249
|
+
//#region src/client/hooks/use-merged-components.ts
|
|
250
|
+
function useMergedComponents(propComponents) {
|
|
251
|
+
const contextComponents = useMdxComponents();
|
|
252
|
+
return useMemo(() => {
|
|
253
|
+
if (!propComponents) return contextComponents;
|
|
254
|
+
const merged = { ...contextComponents };
|
|
255
|
+
const mergedFrontmatter = { ...contextComponents.Frontmatter || {} };
|
|
256
|
+
let hasPropFrontmatter = false;
|
|
257
|
+
Object.entries(propComponents).forEach(([key, value]) => {
|
|
258
|
+
if (key.startsWith("Frontmatter_")) {
|
|
259
|
+
const cleanKey = key.slice(12);
|
|
260
|
+
mergedFrontmatter[cleanKey] = value;
|
|
261
|
+
hasPropFrontmatter = true;
|
|
262
|
+
} else if (key === "Frontmatter" && value && typeof value === "object") {
|
|
263
|
+
Object.assign(mergedFrontmatter, value);
|
|
264
|
+
hasPropFrontmatter = true;
|
|
265
|
+
} else merged[key] = value;
|
|
266
|
+
});
|
|
267
|
+
if (hasPropFrontmatter || contextComponents.Frontmatter) merged.Frontmatter = mergedFrontmatter;
|
|
268
|
+
return merged;
|
|
269
|
+
}, [contextComponents, propComponents]);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region src/client/app/doc-page.tsx
|
|
274
|
+
/**
|
|
275
|
+
* DocPage renders the MDX content and page-specific metadata.
|
|
276
|
+
* It is rendered inside the Outlet of DocsLayout.
|
|
277
|
+
*/
|
|
278
|
+
function DocPage({ route, content: Content, mdxComponents: propComponents }) {
|
|
279
|
+
const allComponents = useMergedComponents(propComponents);
|
|
280
|
+
const { LastUpdated } = allComponents;
|
|
281
|
+
if (!Content) return null;
|
|
282
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Content, { components: allComponents }), route?.lastUpdated && /* @__PURE__ */ jsx(LastUpdated, { date: route.lastUpdated })] });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region src/client/ssg/mdx-page.tsx
|
|
287
|
+
/**
|
|
288
|
+
* Renders an MDX page by consuming pre-loaded route data.
|
|
289
|
+
*
|
|
290
|
+
* - If the route belongs to a collection (`data.collection` is set), renders
|
|
291
|
+
* the custom post component if provided, else falls back to the standard DocPage.
|
|
292
|
+
* - Otherwise, renders the standard `DocPage` layout.
|
|
293
|
+
*/
|
|
294
|
+
function MdxPage({ MDXComponent, mdxComponents: propComponents, collectionPostComponent: CollectionPost }) {
|
|
295
|
+
const data = useLoaderData();
|
|
296
|
+
if (!MDXComponent) return null;
|
|
297
|
+
if (!!data?.collection && CollectionPost) return /* @__PURE__ */ jsx(CollectionPost, {
|
|
298
|
+
MDXComponent,
|
|
299
|
+
mdxComponents: propComponents
|
|
300
|
+
});
|
|
301
|
+
const docData = data;
|
|
302
|
+
return /* @__PURE__ */ jsx(DocPage, {
|
|
303
|
+
route: {
|
|
304
|
+
path: docData.path,
|
|
305
|
+
filePath: docData.filePath,
|
|
306
|
+
title: docData.frontmatter?.title,
|
|
307
|
+
description: docData.frontmatter?.description,
|
|
308
|
+
headings: docData.headings,
|
|
309
|
+
locale: docData.locale,
|
|
310
|
+
version: docData.version,
|
|
311
|
+
group: docData.group,
|
|
312
|
+
groupTitle: docData.groupTitle,
|
|
313
|
+
lastUpdated: docData.lastUpdated,
|
|
314
|
+
frontmatter: docData.frontmatter
|
|
315
|
+
},
|
|
316
|
+
content: MDXComponent,
|
|
317
|
+
mdxComponents: propComponents
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
51
321
|
//#endregion
|
|
52
322
|
//#region src/client/hooks/use-breadcrumbs.ts
|
|
53
323
|
/**
|
|
@@ -98,10 +368,20 @@ function Breadcrumbs() {
|
|
|
98
368
|
//#region src/client/components/ui-base/copy-markdown.tsx
|
|
99
369
|
const useCopyMarkdown = (content) => {
|
|
100
370
|
const [copied, setCopied] = useState(false);
|
|
371
|
+
const timerRef = useRef(null);
|
|
372
|
+
useEffect(() => {
|
|
373
|
+
return () => {
|
|
374
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
375
|
+
};
|
|
376
|
+
}, []);
|
|
101
377
|
const handleCopy = () => {
|
|
102
378
|
navigator.clipboard.writeText(content);
|
|
103
379
|
setCopied(true);
|
|
104
|
-
|
|
380
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
381
|
+
timerRef.current = setTimeout(() => {
|
|
382
|
+
setCopied(false);
|
|
383
|
+
timerRef.current = null;
|
|
384
|
+
}, 2e3);
|
|
105
385
|
};
|
|
106
386
|
const handleOpenRaw = () => {
|
|
107
387
|
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
|
@@ -426,8 +706,8 @@ function useTabs(tabs = [], routes = []) {
|
|
|
426
706
|
transform: "translateX(0) scaleX(0)",
|
|
427
707
|
width: 0
|
|
428
708
|
});
|
|
429
|
-
const currentPath = normalizePath
|
|
430
|
-
const activeTabId = routes.find((r) => normalizePath
|
|
709
|
+
const currentPath = normalizePath(location.pathname);
|
|
710
|
+
const activeTabId = routes.find((r) => normalizePath(r.path) === currentPath)?.tab?.toLowerCase();
|
|
431
711
|
const activeIndex = tabs.findIndex((tab) => tab.id.toLowerCase() === activeTabId);
|
|
432
712
|
const finalActiveIndex = activeIndex === -1 ? 0 : activeIndex;
|
|
433
713
|
useEffect(() => {
|
|
@@ -485,11 +765,11 @@ function Tabs({ tabs, routes }) {
|
|
|
485
765
|
return /* @__PURE__ */ jsx("div", {
|
|
486
766
|
className: "mx-auto max-w-(--breakpoint-3xl) px-4 md:px-6 select-none",
|
|
487
767
|
children: /* @__PURE__ */ jsxs(Tabs$1.List, {
|
|
488
|
-
className: "border-none py-0 scrollbar-hide relative flex flex-row items-center",
|
|
768
|
+
className: "border-none py-0 scrollbar-hide relative flex flex-row items-center overflow-x-auto",
|
|
489
769
|
children: [tabs.map((tab, index) => {
|
|
490
770
|
const isActive = index === activeIndex;
|
|
491
771
|
const firstRoute = routes.find((r) => r.tab && r.tab.toLowerCase() === tab.id.toLowerCase());
|
|
492
|
-
return /* @__PURE__ */ jsxs(Link, {
|
|
772
|
+
return /* @__PURE__ */ jsxs(Link$1, {
|
|
493
773
|
href: firstRoute ? firstRoute.path : "#",
|
|
494
774
|
ref: (el) => {
|
|
495
775
|
tabRefs.current[index] = el;
|
|
@@ -554,7 +834,7 @@ function useVersion() {
|
|
|
554
834
|
currentVersion,
|
|
555
835
|
currentVersionLabel: (versions?.versions?.find?.((v) => v.path === currentVersion))?.label || currentVersion,
|
|
556
836
|
availableVersions: useMemo(() => {
|
|
557
|
-
return versions ? versions.versions.map((v) => ({
|
|
837
|
+
return versions?.versions ? versions.versions.map((v) => ({
|
|
558
838
|
key: v.path,
|
|
559
839
|
label: v.label,
|
|
560
840
|
value: v.path,
|
|
@@ -693,15 +973,14 @@ function I18nSelector({ className }) {
|
|
|
693
973
|
|
|
694
974
|
//#endregion
|
|
695
975
|
//#region src/client/components/ui-base/navbar.tsx
|
|
696
|
-
const SearchDialog$1 = lazy(() => import("../search-dialog-
|
|
976
|
+
const SearchDialog$1 = lazy(() => import("../search-dialog-DHc_8FFX.js").then((m) => ({ default: m.SearchDialog })));
|
|
697
977
|
function Navbar() {
|
|
698
978
|
const { links, title, logo, logoProps, github, social, config } = useNavbar();
|
|
699
|
-
const { routes,
|
|
700
|
-
const { pathname } = useLocation$1();
|
|
979
|
+
const { routes, currentRoute, isCollectionPage, currentVersion, currentLocale } = useRoutes();
|
|
701
980
|
const { isSidebarOpen, toggleSidebar } = useUI();
|
|
702
981
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
703
982
|
const themeConfig = config.theme || {};
|
|
704
|
-
const isDocs = !!currentRoute?.filePath;
|
|
983
|
+
const isDocs = !!currentRoute?.filePath && !isCollectionPage;
|
|
705
984
|
const hasTabs = themeConfig?.tabs && themeConfig.tabs.length > 0;
|
|
706
985
|
return /* @__PURE__ */ jsxs(Navbar$1.Root, {
|
|
707
986
|
className: cn("border-b border-subtle bg-main/80 backdrop-blur-md", hasTabs && "border-b-0"),
|
|
@@ -802,7 +1081,7 @@ function Navbar() {
|
|
|
802
1081
|
className: "w-full border-b border-subtle bg-main",
|
|
803
1082
|
children: /* @__PURE__ */ jsx(Tabs, {
|
|
804
1083
|
tabs: themeConfig.tabs,
|
|
805
|
-
routes:
|
|
1084
|
+
routes: routes || []
|
|
806
1085
|
})
|
|
807
1086
|
})
|
|
808
1087
|
]
|
|
@@ -855,38 +1134,6 @@ function NavbarMobileLinkItem({ link, onClose }) {
|
|
|
855
1134
|
});
|
|
856
1135
|
}
|
|
857
1136
|
|
|
858
|
-
//#endregion
|
|
859
|
-
//#region src/client/components/ui-base/not-found.tsx
|
|
860
|
-
function NotFound() {
|
|
861
|
-
return /* @__PURE__ */ jsx("div", {
|
|
862
|
-
className: "flex items-center justify-center min-h-[65vh] text-center px-4",
|
|
863
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
864
|
-
className: "space-y-6 max-w-md mx-auto p-8 border border-subtle bg-surface rounded-2xl shadow-xs",
|
|
865
|
-
children: [
|
|
866
|
-
/* @__PURE__ */ jsx("span", {
|
|
867
|
-
className: "block text-7xl font-extrabold tracking-tight text-primary-500",
|
|
868
|
-
children: "404"
|
|
869
|
-
}),
|
|
870
|
-
/* @__PURE__ */ jsxs("div", {
|
|
871
|
-
className: "space-y-2",
|
|
872
|
-
children: [/* @__PURE__ */ jsx("h1", {
|
|
873
|
-
className: "text-xl font-bold text-body",
|
|
874
|
-
children: "Page Not Found"
|
|
875
|
-
}), /* @__PURE__ */ jsx("p", {
|
|
876
|
-
className: "text-sm text-muted leading-relaxed",
|
|
877
|
-
children: "The page you're looking for doesn't exist or has been moved."
|
|
878
|
-
})]
|
|
879
|
-
}),
|
|
880
|
-
/* @__PURE__ */ jsxs(Link, {
|
|
881
|
-
href: "/",
|
|
882
|
-
className: "inline-flex items-center gap-2 rounded-xl border border-subtle bg-main px-6 py-2.5 text-xs font-semibold text-body hover:bg-primary-50/50 hover:border-primary-500/50 transition-all duration-300 outline-none select-none",
|
|
883
|
-
children: [/* @__PURE__ */ jsx(ArrowLeft, { size: 14 }), " Go to Home"]
|
|
884
|
-
})
|
|
885
|
-
]
|
|
886
|
-
})
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
|
|
890
1137
|
//#endregion
|
|
891
1138
|
//#region src/client/components/ui-base/on-this-page.tsx
|
|
892
1139
|
function OnThisPage({ headings = [], editLink, communityHelp, filePath }) {
|
|
@@ -1037,249 +1284,71 @@ const Sidebar = Object.assign(SidebarMain, {
|
|
|
1037
1284
|
});
|
|
1038
1285
|
|
|
1039
1286
|
//#endregion
|
|
1040
|
-
//#region src/client/components/ui-base/
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
});
|
|
1287
|
+
//#region src/client/components/ui-base/banner.tsx
|
|
1288
|
+
function Banner({ children, className = "", dismissible = false, id = "boltdocs-banner", ...props }) {
|
|
1289
|
+
const [isVisible, setIsVisible] = useState(true);
|
|
1290
|
+
useEffect(() => {
|
|
1291
|
+
if (dismissible && id) {
|
|
1292
|
+
if (localStorage.getItem(`boltdocs-banner-dismissed-${id}`) === "true") setIsVisible(false);
|
|
1293
|
+
}
|
|
1294
|
+
}, [dismissible, id]);
|
|
1295
|
+
const handleDismiss = () => {
|
|
1296
|
+
setIsVisible(false);
|
|
1297
|
+
if (dismissible && id) localStorage.setItem(`boltdocs-banner-dismissed-${id}`, "true");
|
|
1298
|
+
};
|
|
1299
|
+
if (!isVisible) return null;
|
|
1054
1300
|
return /* @__PURE__ */ jsxs("div", {
|
|
1055
|
-
className: "
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1301
|
+
className: cn("relative flex items-center justify-center px-4 py-2.5 text-xs font-semibold tracking-wide bg-primary-500/10 dark:bg-primary-500/15 text-primary-700 dark:text-primary-300 border-b border-primary-500/20 select-none animate-in fade-in duration-300", className),
|
|
1302
|
+
...props,
|
|
1303
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1304
|
+
className: "flex-1 text-center flex items-center justify-center gap-2",
|
|
1305
|
+
children
|
|
1306
|
+
}), dismissible && /* @__PURE__ */ jsx("button", {
|
|
1307
|
+
onClick: handleDismiss,
|
|
1308
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 p-1.5 opacity-70 hover:opacity-100 transition-all duration-300 rounded-xl hover:bg-primary-500/10 cursor-pointer border-none bg-transparent flex items-center justify-center outline-none",
|
|
1309
|
+
"aria-label": "Dismiss banner",
|
|
1310
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-3.5 h-3.5" })
|
|
1059
1311
|
})]
|
|
1060
1312
|
});
|
|
1061
1313
|
}
|
|
1062
1314
|
|
|
1063
1315
|
//#endregion
|
|
1064
|
-
//#region src/client/
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
function
|
|
1070
|
-
|
|
1071
|
-
const allComponents = useMemo(() => ({
|
|
1072
|
-
LastUpdated,
|
|
1073
|
-
...contextComponents,
|
|
1074
|
-
...propComponents
|
|
1075
|
-
}), [contextComponents, propComponents]);
|
|
1076
|
-
const LastUpdated$1 = allComponents.LastUpdated || LastUpdated;
|
|
1077
|
-
if (!Content) return null;
|
|
1078
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Content, { components: allComponents }), route?.lastUpdated && /* @__PURE__ */ jsx(LastUpdated$1, { date: route.lastUpdated })] });
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
//#endregion
|
|
1082
|
-
//#region src/client/ssg/mdx-page.tsx
|
|
1083
|
-
/**
|
|
1084
|
-
* Renders an MDX page by consuming pre-loaded module data.
|
|
1085
|
-
* Uses DocPage to ensure consistent layout and metadata application.
|
|
1086
|
-
*/
|
|
1087
|
-
function MdxPage({ MDXComponent: propMDX, mdxComponents: propComponents }) {
|
|
1088
|
-
const data = useLoaderData();
|
|
1089
|
-
const MDXComponent = propMDX || data?.MDXComponent;
|
|
1090
|
-
const components = propComponents || data?.mdxComponents;
|
|
1091
|
-
if (!MDXComponent) return null;
|
|
1092
|
-
return /* @__PURE__ */ jsx(DocPage, {
|
|
1093
|
-
route: {
|
|
1094
|
-
path: data.path,
|
|
1095
|
-
filePath: data.filePath,
|
|
1096
|
-
title: data.frontmatter.title,
|
|
1097
|
-
description: data.frontmatter.description,
|
|
1098
|
-
headings: data.headings,
|
|
1099
|
-
locale: data.locale,
|
|
1100
|
-
version: data.version,
|
|
1101
|
-
group: data.group,
|
|
1102
|
-
groupTitle: data.groupTitle,
|
|
1103
|
-
lastUpdated: data.lastUpdated,
|
|
1104
|
-
frontmatter: data.frontmatter
|
|
1105
|
-
},
|
|
1106
|
-
content: MDXComponent,
|
|
1107
|
-
mdxComponents: components
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
//#endregion
|
|
1112
|
-
//#region src/client/app/helmet-compat.tsx
|
|
1113
|
-
const mod = ReactHelmetAsync;
|
|
1114
|
-
/**
|
|
1115
|
-
* The `<Helmet>` component, resolved across CJS/ESM module shapes.
|
|
1116
|
-
* Falls back to a transparent fragment wrapper if the module cannot be resolved.
|
|
1117
|
-
*/
|
|
1118
|
-
const Helmet = mod.Helmet || mod.default?.Helmet || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
1119
|
-
/**
|
|
1120
|
-
* The `<HelmetProvider>` component, resolved across CJS/ESM module shapes.
|
|
1121
|
-
* Falls back to a transparent fragment wrapper if the module cannot be resolved.
|
|
1122
|
-
*/
|
|
1123
|
-
const HelmetProvider = mod.HelmetProvider || mod.default?.HelmetProvider || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
1124
|
-
|
|
1125
|
-
//#endregion
|
|
1126
|
-
//#region src/client/app/scroll-handler.tsx
|
|
1127
|
-
/**
|
|
1128
|
-
* Handles scroll restoration and hash scrolling on navigation.
|
|
1129
|
-
* It ensures the page scrolls to top on pathname changes,
|
|
1130
|
-
* or specifically to an anchor element if a hash is present.
|
|
1131
|
-
*/
|
|
1132
|
-
function ScrollHandler() {
|
|
1133
|
-
const { pathname, hash } = useLocation$1();
|
|
1134
|
-
const handleScroll = (behavior = "auto") => {
|
|
1135
|
-
const container = document.querySelector(".boltdocs-content") || window;
|
|
1136
|
-
const getScrollTop = () => {
|
|
1137
|
-
if (container === window) return window.scrollY;
|
|
1138
|
-
return container.scrollTop;
|
|
1139
|
-
};
|
|
1140
|
-
const scrollTo = (top, scrollBehavior) => {
|
|
1141
|
-
if (container === window) window.scrollTo({
|
|
1142
|
-
top,
|
|
1143
|
-
behavior: scrollBehavior
|
|
1144
|
-
});
|
|
1145
|
-
else container.scrollTo({
|
|
1146
|
-
top,
|
|
1147
|
-
behavior: scrollBehavior
|
|
1148
|
-
});
|
|
1149
|
-
};
|
|
1150
|
-
if (hash) {
|
|
1151
|
-
const id = hash.replace("#", "");
|
|
1152
|
-
const element = document.getElementById(id);
|
|
1153
|
-
if (element) {
|
|
1154
|
-
const offset = 80;
|
|
1155
|
-
const containerTop = container === window ? 0 : container.getBoundingClientRect().top;
|
|
1156
|
-
scrollTo(element.getBoundingClientRect().top - containerTop - offset + getScrollTop(), behavior);
|
|
1157
|
-
return true;
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
scrollTo(0, behavior);
|
|
1161
|
-
return false;
|
|
1162
|
-
};
|
|
1163
|
-
useLayoutEffect(() => {
|
|
1164
|
-
handleScroll("auto");
|
|
1165
|
-
}, [pathname, hash]);
|
|
1166
|
-
useEffect(() => {
|
|
1167
|
-
handleScroll("auto");
|
|
1168
|
-
const rafId = requestAnimationFrame(() => {
|
|
1169
|
-
handleScroll("auto");
|
|
1170
|
-
window.dispatchEvent(new Event("resize"));
|
|
1171
|
-
});
|
|
1172
|
-
return () => cancelAnimationFrame(rafId);
|
|
1173
|
-
}, [pathname, hash]);
|
|
1174
|
-
return null;
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
//#endregion
|
|
1178
|
-
//#region src/client/app/mdx-component.tsx
|
|
1179
|
-
const mdxComponentsDefault = {
|
|
1180
|
-
...mdx_components_default,
|
|
1181
|
-
NotFound,
|
|
1182
|
-
"404": NotFound
|
|
1183
|
-
};
|
|
1184
|
-
|
|
1185
|
-
//#endregion
|
|
1186
|
-
//#region src/client/ssg/boltdocs-shell.tsx
|
|
1187
|
-
/** Normalize a path: strip trailing slash unless it is exactly '/'. */
|
|
1188
|
-
function normalizePath(p) {
|
|
1189
|
-
return p.endsWith("/") && p.length > 1 ? p.slice(0, -1) : p;
|
|
1316
|
+
//#region src/client/ssg/mdx-elements.tsx
|
|
1317
|
+
const Loading = () => /* @__PURE__ */ jsx("div", {
|
|
1318
|
+
className: "text-muted text-sm py-4",
|
|
1319
|
+
children: "Loading..."
|
|
1320
|
+
});
|
|
1321
|
+
function resolveModuleLoader(loader) {
|
|
1322
|
+
return typeof loader === "function" ? loader() : Promise.resolve(loader);
|
|
1190
1323
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
*/
|
|
1194
|
-
function I18nUpdater({ config }) {
|
|
1195
|
-
const { currentLocale } = useBoltdocsContext();
|
|
1324
|
+
const EagerMdxElement = ({ moduleLoader, moduleKey, route, components, collectionPostComponent }) => {
|
|
1325
|
+
const [mod, setMod] = useState(moduleLoader);
|
|
1196
1326
|
useEffect(() => {
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
const localeConfig = config.i18n.localeConfigs?.[locale];
|
|
1200
|
-
document.documentElement.lang = localeConfig?.htmlLang || locale || "en";
|
|
1201
|
-
document.documentElement.dir = localeConfig?.direction || "ltr";
|
|
1202
|
-
}, [currentLocale, config.i18n]);
|
|
1203
|
-
return null;
|
|
1204
|
-
}
|
|
1205
|
-
/**
|
|
1206
|
-
* Synchronizes the Zustand store with the current URL pathname.
|
|
1207
|
-
* Receives a pre-built Map for O(1) route lookups instead of O(n) .find().
|
|
1208
|
-
*/
|
|
1209
|
-
function StoreSync({ config, routeMap }) {
|
|
1210
|
-
const location = useLocation$1();
|
|
1211
|
-
const { setLocale, setVersion } = useBoltdocsContext();
|
|
1327
|
+
setMod(moduleLoader);
|
|
1328
|
+
}, [moduleLoader]);
|
|
1212
1329
|
useEffect(() => {
|
|
1213
|
-
|
|
1214
|
-
const
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
}, [
|
|
1220
|
-
location.pathname,
|
|
1221
|
-
config,
|
|
1222
|
-
routeMap,
|
|
1223
|
-
setLocale,
|
|
1224
|
-
setVersion
|
|
1225
|
-
]);
|
|
1226
|
-
return null;
|
|
1227
|
-
}
|
|
1228
|
-
function BoltdocsShell({ config, routes, components = {} }) {
|
|
1229
|
-
const allComponents = useMemo(() => ({
|
|
1230
|
-
...mdxComponentsDefault,
|
|
1231
|
-
...virtualCustomComponents,
|
|
1232
|
-
...components
|
|
1233
|
-
}), [components]);
|
|
1234
|
-
const { pathname } = useLocation$1();
|
|
1235
|
-
const currentPath = useMemo(() => normalizePath(pathname || "/"), [pathname]);
|
|
1236
|
-
const routeMap = useMemo(() => {
|
|
1237
|
-
const map = /* @__PURE__ */ new Map();
|
|
1238
|
-
for (const r of routes) {
|
|
1239
|
-
const key = normalizePath(r.path === "" ? "/" : r.path);
|
|
1240
|
-
map.set(key, r);
|
|
1241
|
-
}
|
|
1242
|
-
return map;
|
|
1243
|
-
}, [routes]);
|
|
1244
|
-
const initialData = useMemo(() => {
|
|
1245
|
-
const matched = routeMap.get(currentPath);
|
|
1246
|
-
let initLocale = void 0;
|
|
1247
|
-
let initVersion = void 0;
|
|
1248
|
-
if (matched) {
|
|
1249
|
-
if (config.i18n) initLocale = matched.locale || config.i18n.defaultLocale;
|
|
1250
|
-
if (config.versions) initVersion = matched.version || config.versions.defaultVersion;
|
|
1251
|
-
}
|
|
1252
|
-
return {
|
|
1253
|
-
initLocale,
|
|
1254
|
-
initVersion
|
|
1330
|
+
if (!import.meta.hot || !moduleKey) return;
|
|
1331
|
+
const handler = (data) => {
|
|
1332
|
+
if (data.relPath.replace(/\\/g, "/").replace(/^\//, "") !== route.filePath.replace(/\\/g, "/").replace(/^\//, "")) return;
|
|
1333
|
+
import(moduleKey + "?t=" + Date.now()).then((m) => {
|
|
1334
|
+
setMod(m);
|
|
1335
|
+
});
|
|
1255
1336
|
};
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
return /* @__PURE__ */ jsx(
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
/* @__PURE__ */ jsx(StoreSync, {
|
|
1272
|
-
config,
|
|
1273
|
-
routeMap
|
|
1274
|
-
}),
|
|
1275
|
-
/* @__PURE__ */ jsx(I18nUpdater, { config }),
|
|
1276
|
-
/* @__PURE__ */ jsx(Outlet, {})
|
|
1277
|
-
]
|
|
1278
|
-
})]
|
|
1279
|
-
})
|
|
1280
|
-
}) }) })
|
|
1281
|
-
}) });
|
|
1282
|
-
}
|
|
1337
|
+
import.meta.hot.on("boltdocs:mdx-update", handler);
|
|
1338
|
+
return () => import.meta.hot?.off("boltdocs:mdx-update", handler);
|
|
1339
|
+
}, [moduleKey, route.filePath]);
|
|
1340
|
+
const MDXComponent = mod?.default ?? mod ?? null;
|
|
1341
|
+
if (!MDXComponent) return /* @__PURE__ */ jsx(Loading, {});
|
|
1342
|
+
return /* @__PURE__ */ jsx(MdxPage, {
|
|
1343
|
+
MDXComponent,
|
|
1344
|
+
mdxComponents: components,
|
|
1345
|
+
collectionPostComponent
|
|
1346
|
+
});
|
|
1347
|
+
};
|
|
1348
|
+
const NotFoundWrapper = () => {
|
|
1349
|
+
const components = useMdxComponents();
|
|
1350
|
+
return /* @__PURE__ */ jsx(components.NotFound || components["404"] || NotFound, {});
|
|
1351
|
+
};
|
|
1283
1352
|
|
|
1284
1353
|
//#endregion
|
|
1285
1354
|
//#region src/client/app/head.tsx
|
|
@@ -1294,6 +1363,8 @@ function Head({ siteTitle, siteDescription, routes }) {
|
|
|
1294
1363
|
const translatedSiteTitle = getTranslated(siteTitle, currentLocale);
|
|
1295
1364
|
const finalTitle = pageTitle ? `${pageTitle} | ${translatedSiteTitle}` : translatedSiteTitle;
|
|
1296
1365
|
const seo = currentRoute?.seo || {};
|
|
1366
|
+
const canonicalUrl = seo.canonical || (config?.siteUrl && currentRoute?.path ? `${config.siteUrl.replace(/\/$/, "")}${currentRoute.path}` : void 0);
|
|
1367
|
+
const ogUrl = seo["og:url"] || canonicalUrl || (typeof window !== "undefined" ? window.location.href : void 0);
|
|
1297
1368
|
const globalMetatags = config?.seo?.metatags || {};
|
|
1298
1369
|
const defaultOgImage = config?.seo?.thumbnails?.background;
|
|
1299
1370
|
const ogImage = seo["og:image"] || defaultOgImage;
|
|
@@ -1315,13 +1386,13 @@ function Head({ siteTitle, siteDescription, routes }) {
|
|
|
1315
1386
|
property: "og:type",
|
|
1316
1387
|
content: "article"
|
|
1317
1388
|
}),
|
|
1318
|
-
|
|
1319
|
-
property: "og:url",
|
|
1320
|
-
content: window.location.href
|
|
1321
|
-
}),
|
|
1322
|
-
typeof window !== "undefined" && /* @__PURE__ */ jsx("link", {
|
|
1389
|
+
canonicalUrl && /* @__PURE__ */ jsx("link", {
|
|
1323
1390
|
rel: "canonical",
|
|
1324
|
-
href:
|
|
1391
|
+
href: canonicalUrl
|
|
1392
|
+
}),
|
|
1393
|
+
ogUrl && /* @__PURE__ */ jsx("meta", {
|
|
1394
|
+
property: "og:url",
|
|
1395
|
+
content: ogUrl
|
|
1325
1396
|
}),
|
|
1326
1397
|
/* @__PURE__ */ jsx("meta", {
|
|
1327
1398
|
name: "twitter:card",
|
|
@@ -1365,10 +1436,7 @@ function Head({ siteTitle, siteDescription, routes }) {
|
|
|
1365
1436
|
name: "robots",
|
|
1366
1437
|
content: value
|
|
1367
1438
|
}, "robots");
|
|
1368
|
-
if (key === "canonical"
|
|
1369
|
-
rel: "canonical",
|
|
1370
|
-
href: value
|
|
1371
|
-
}, "canonical");
|
|
1439
|
+
if (key === "canonical" || key === "og:url") return null;
|
|
1372
1440
|
return key.startsWith("og:") || key.startsWith("music:") || key.startsWith("video:") || key.startsWith("article:") || key.startsWith("book:") || key.startsWith("profile:") ? /* @__PURE__ */ jsx("meta", {
|
|
1373
1441
|
property: key,
|
|
1374
1442
|
content: value
|
|
@@ -1380,71 +1448,68 @@ function Head({ siteTitle, siteDescription, routes }) {
|
|
|
1380
1448
|
] });
|
|
1381
1449
|
}
|
|
1382
1450
|
|
|
1451
|
+
//#endregion
|
|
1452
|
+
//#region src/client/collections/collections-context.tsx
|
|
1453
|
+
const CollectionsContext = createContext({});
|
|
1454
|
+
function useCollectionsData() {
|
|
1455
|
+
return use(CollectionsContext);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1383
1458
|
//#endregion
|
|
1384
1459
|
//#region src/client/app/docs-layout.tsx
|
|
1385
|
-
|
|
1386
|
-
* Wraps the docs Outlet with the user's (or default) layout component.
|
|
1387
|
-
* The Layout receives the routed page as `children`.
|
|
1388
|
-
* We use useRoutes to pass the current route context to the persistent layout.
|
|
1389
|
-
*/
|
|
1390
|
-
function DocsLayout$1() {
|
|
1460
|
+
function DocsLayout({ collectionsData }) {
|
|
1391
1461
|
const config = useConfig();
|
|
1392
1462
|
const { currentRoute, allRoutes } = useRoutes();
|
|
1393
|
-
|
|
1463
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Head, {
|
|
1394
1464
|
siteTitle: config.theme?.title,
|
|
1395
1465
|
siteDescription: config.theme?.description,
|
|
1396
1466
|
routes: allRoutes || []
|
|
1397
|
-
}), /* @__PURE__ */ jsx(UserLayout, {
|
|
1467
|
+
}), /* @__PURE__ */ jsx(InternalErrorBoundary, { children: /* @__PURE__ */ jsx(UserLayout, {
|
|
1398
1468
|
route: currentRoute,
|
|
1399
1469
|
children: /* @__PURE__ */ jsx(Outlet, {})
|
|
1400
|
-
})] });
|
|
1470
|
+
}) })] });
|
|
1471
|
+
if (collectionsData) return /* @__PURE__ */ jsx(CollectionsContext.Provider, {
|
|
1472
|
+
value: collectionsData,
|
|
1473
|
+
children: content
|
|
1474
|
+
});
|
|
1475
|
+
return content;
|
|
1401
1476
|
}
|
|
1402
1477
|
|
|
1403
1478
|
//#endregion
|
|
1404
|
-
//#region src/client/ssg/create-routes.
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
});
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
const
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
function createRoutes(options) {
|
|
1435
|
-
const { routesData, config, mdxModules, externalPages, externalLayout, components } = options;
|
|
1436
|
-
const EffectiveExternalLayout = externalLayout || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
1437
|
-
const withBase = (path) => {
|
|
1438
|
-
const base = config.base || "/";
|
|
1439
|
-
if (path.startsWith(base)) return path;
|
|
1440
|
-
return `${base === "/" ? "" : base.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}` || "/";
|
|
1441
|
-
};
|
|
1479
|
+
//#region src/client/ssg/create-routes.utils.ts
|
|
1480
|
+
function withBase(path, config) {
|
|
1481
|
+
const base = config.base || "/";
|
|
1482
|
+
if (path.startsWith(base)) return path;
|
|
1483
|
+
return `${base === "/" ? "" : base.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}` || "/";
|
|
1484
|
+
}
|
|
1485
|
+
function buildModuleMap(mdxModules) {
|
|
1486
|
+
const moduleMap = /* @__PURE__ */ new Map();
|
|
1487
|
+
const mdxModuleKeys = Object.keys(mdxModules);
|
|
1488
|
+
if (mdxModuleKeys.length > 0) {
|
|
1489
|
+
const docsDirName = mdxModuleKeys[0].replace(/\\/g, "/").split("/").filter(Boolean)[0] || "docs";
|
|
1490
|
+
const primaryPrefix = `/${docsDirName}/`;
|
|
1491
|
+
const altPrefix = `./${docsDirName}/`;
|
|
1492
|
+
for (const rawKey of mdxModuleKeys) {
|
|
1493
|
+
const k = rawKey.replace(/\\/g, "/");
|
|
1494
|
+
let relativePath = "";
|
|
1495
|
+
if (k.indexOf(primaryPrefix) !== -1) relativePath = k.substring(k.indexOf(primaryPrefix) + primaryPrefix.length);
|
|
1496
|
+
else if (k.startsWith(altPrefix)) relativePath = k.substring(altPrefix.length);
|
|
1497
|
+
if (relativePath) moduleMap.set(relativePath, rawKey);
|
|
1498
|
+
else moduleMap.set(k, rawKey);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
return moduleMap;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
//#endregion
|
|
1505
|
+
//#region src/client/ssg/create-routes.doc.tsx
|
|
1506
|
+
function buildDocRoutes(options) {
|
|
1507
|
+
const { routesData, config, mdxModules, components, externalPages } = options;
|
|
1508
|
+
const baseDocsPath = (config.base || "/docs").replace(/\/$/, "") || "/";
|
|
1442
1509
|
const defaultVersionMetadata = [];
|
|
1443
1510
|
const defaultVersion = config.versions?.defaultVersion;
|
|
1444
1511
|
const docsBase = (config.base || "/docs").replace(/\/$/, "");
|
|
1445
|
-
|
|
1446
|
-
if (!baseDocsPath) baseDocsPath = "/";
|
|
1447
|
-
if (defaultVersion) routesData.forEach((route) => {
|
|
1512
|
+
if (defaultVersion) routesData.filter((r) => !r.collection).forEach((route) => {
|
|
1448
1513
|
if (route.version) return;
|
|
1449
1514
|
const p = route.path || "";
|
|
1450
1515
|
const subPath = p.startsWith(docsBase) ? p.substring(docsBase.length).replace(/^\//, "") : p.replace(/^\//, "");
|
|
@@ -1457,36 +1522,18 @@ function createRoutes(options) {
|
|
|
1457
1522
|
});
|
|
1458
1523
|
}
|
|
1459
1524
|
});
|
|
1460
|
-
const docMetadata = [...routesData, ...defaultVersionMetadata];
|
|
1461
|
-
const moduleMap =
|
|
1525
|
+
const docMetadata = [...routesData.filter((r) => !r.collection), ...defaultVersionMetadata];
|
|
1526
|
+
const moduleMap = buildModuleMap(mdxModules);
|
|
1462
1527
|
const mdxModuleKeys = Object.keys(mdxModules);
|
|
1463
|
-
|
|
1464
|
-
const docsDirName = mdxModuleKeys[0].replace(/\\/g, "/").split("/").filter(Boolean)[0] || "docs";
|
|
1465
|
-
const primaryPrefix = `/${docsDirName}/`;
|
|
1466
|
-
const altPrefix = `./${docsDirName}/`;
|
|
1467
|
-
for (const rawKey of mdxModuleKeys) {
|
|
1468
|
-
const k = rawKey.replace(/\\/g, "/");
|
|
1469
|
-
let relativePath = "";
|
|
1470
|
-
if (k.indexOf(primaryPrefix) !== -1) relativePath = k.substring(k.indexOf(primaryPrefix) + primaryPrefix.length);
|
|
1471
|
-
else if (k.startsWith(altPrefix)) relativePath = k.substring(altPrefix.length);
|
|
1472
|
-
if (relativePath) moduleMap.set(relativePath, rawKey);
|
|
1473
|
-
else moduleMap.set(k, rawKey);
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1528
|
+
const isLazy = mdxModuleKeys.length > 0 && typeof mdxModules[mdxModuleKeys[0]] === "function";
|
|
1476
1529
|
const docRoutes = docMetadata.map((route) => {
|
|
1477
1530
|
const normalizedFilePath = route.filePath.replace(/\\/g, "/");
|
|
1478
1531
|
const moduleKey = moduleMap.get(normalizedFilePath);
|
|
1479
1532
|
const moduleLoader = moduleKey ? mdxModules[moduleKey] : null;
|
|
1480
|
-
const fullPath = withBase(route.path === "" ? "/" : route.path);
|
|
1533
|
+
const fullPath = withBase(route.path === "" ? "/" : route.path, config);
|
|
1481
1534
|
const path = fullPath === baseDocsPath ? "." : fullPath.startsWith(baseDocsPath + "/") ? fullPath.slice(baseDocsPath.length + 1) : fullPath;
|
|
1482
|
-
|
|
1535
|
+
const routeRecord = {
|
|
1483
1536
|
path,
|
|
1484
|
-
element: /* @__PURE__ */ jsx(MdxRouteElement, {
|
|
1485
|
-
moduleKey,
|
|
1486
|
-
moduleLoader,
|
|
1487
|
-
route,
|
|
1488
|
-
components
|
|
1489
|
-
}, moduleKey || path),
|
|
1490
1537
|
loader: async () => ({
|
|
1491
1538
|
path,
|
|
1492
1539
|
frontmatter: {
|
|
@@ -1494,6 +1541,7 @@ function createRoutes(options) {
|
|
|
1494
1541
|
description: route.description || "",
|
|
1495
1542
|
...route.frontmatter || {}
|
|
1496
1543
|
},
|
|
1544
|
+
seo: route.seo,
|
|
1497
1545
|
headings: route.headings || [],
|
|
1498
1546
|
filePath: route.filePath,
|
|
1499
1547
|
locale: route.locale,
|
|
@@ -1505,6 +1553,24 @@ function createRoutes(options) {
|
|
|
1505
1553
|
}),
|
|
1506
1554
|
getStaticPaths: () => [path]
|
|
1507
1555
|
};
|
|
1556
|
+
if (isLazy && moduleLoader) routeRecord.lazy = async () => {
|
|
1557
|
+
const mod = await resolveModuleLoader(moduleLoader);
|
|
1558
|
+
return { Component: function LoadedMdxRoute() {
|
|
1559
|
+
return /* @__PURE__ */ jsx(EagerMdxElement, {
|
|
1560
|
+
moduleKey,
|
|
1561
|
+
moduleLoader: mod,
|
|
1562
|
+
route,
|
|
1563
|
+
components
|
|
1564
|
+
}, moduleKey || path);
|
|
1565
|
+
} };
|
|
1566
|
+
};
|
|
1567
|
+
else routeRecord.element = /* @__PURE__ */ jsx(EagerMdxElement, {
|
|
1568
|
+
moduleKey,
|
|
1569
|
+
moduleLoader,
|
|
1570
|
+
route,
|
|
1571
|
+
components
|
|
1572
|
+
}, moduleKey || path);
|
|
1573
|
+
return routeRecord;
|
|
1508
1574
|
});
|
|
1509
1575
|
const locales = config.i18n?.locales ? Array.isArray(config.i18n.locales) ? config.i18n.locales : Object.keys(config.i18n.locales) : [];
|
|
1510
1576
|
const allVersions = config.versions?.versions?.map((v) => v.path) || [];
|
|
@@ -1555,11 +1621,11 @@ function createRoutes(options) {
|
|
|
1555
1621
|
getStaticPaths: () => []
|
|
1556
1622
|
});
|
|
1557
1623
|
const matchedMetaObj = docMetadata.find((m) => {
|
|
1558
|
-
const fullPath = withBase(m.path === "" ? "/" : m.path);
|
|
1624
|
+
const fullPath = withBase(m.path === "" ? "/" : m.path, config);
|
|
1559
1625
|
return (fullPath === baseDocsPath ? "." : fullPath.startsWith(baseDocsPath + "/") ? fullPath.slice(baseDocsPath.length + 1) : fullPath) === matchedRouteObj.path;
|
|
1560
1626
|
});
|
|
1561
1627
|
if (matchedMetaObj) {
|
|
1562
|
-
const canonicalPath = withBase(matchedMetaObj.path);
|
|
1628
|
+
const canonicalPath = withBase(matchedMetaObj.path, config);
|
|
1563
1629
|
const canonicalUrl = config.siteUrl ? `${config.siteUrl.replace(/\/$/, "")}${canonicalPath}` : canonicalPath;
|
|
1564
1630
|
docMetadata.push({
|
|
1565
1631
|
...matchedMetaObj,
|
|
@@ -1575,62 +1641,277 @@ function createRoutes(options) {
|
|
|
1575
1641
|
}
|
|
1576
1642
|
}
|
|
1577
1643
|
});
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1644
|
+
return {
|
|
1645
|
+
routes: docRoutes,
|
|
1646
|
+
metadata: docMetadata
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
//#endregion
|
|
1651
|
+
//#region src/client/ssg/create-routes.external.tsx
|
|
1652
|
+
function buildExternalRoutes(options) {
|
|
1653
|
+
const { externalPages, externalLayout, config } = options;
|
|
1654
|
+
const children = [];
|
|
1655
|
+
const metadata = [];
|
|
1656
|
+
if (!externalPages) return {
|
|
1657
|
+
children,
|
|
1658
|
+
metadata
|
|
1659
|
+
};
|
|
1660
|
+
const EffectiveExternalLayout = externalLayout || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
1661
|
+
Object.entries(externalPages).forEach(([rawPath, ExtComponent]) => {
|
|
1585
1662
|
const path = rawPath.startsWith("/") ? rawPath : `/${rawPath}`;
|
|
1586
|
-
|
|
1587
|
-
|
|
1663
|
+
metadata.push({
|
|
1664
|
+
path,
|
|
1665
|
+
locale: config.i18n?.defaultLocale,
|
|
1666
|
+
title: rawPath === "/" ? "Home" : rawPath.replace(/^\//, "").split("/").pop() || "Page",
|
|
1667
|
+
filePath: "",
|
|
1668
|
+
headings: []
|
|
1669
|
+
});
|
|
1670
|
+
children.push({
|
|
1671
|
+
path,
|
|
1672
|
+
element: /* @__PURE__ */ jsx(EffectiveExternalLayout, { children: /* @__PURE__ */ jsx(ExtComponent, {}) }),
|
|
1673
|
+
loader: async () => ({
|
|
1588
1674
|
path,
|
|
1589
|
-
locale: config.i18n?.defaultLocale
|
|
1590
|
-
|
|
1675
|
+
locale: config.i18n?.defaultLocale
|
|
1676
|
+
}),
|
|
1677
|
+
getStaticPaths: () => [path]
|
|
1678
|
+
});
|
|
1679
|
+
if (config.i18n) Object.keys(config.i18n.locales).forEach((locale) => {
|
|
1680
|
+
const localePath = `/${locale}${rawPath === "/" ? "" : rawPath}`;
|
|
1681
|
+
metadata.push({
|
|
1682
|
+
path: localePath,
|
|
1683
|
+
locale,
|
|
1684
|
+
title: rawPath,
|
|
1591
1685
|
filePath: "",
|
|
1592
1686
|
headings: []
|
|
1593
1687
|
});
|
|
1594
1688
|
children.push({
|
|
1595
|
-
path,
|
|
1689
|
+
path: localePath,
|
|
1596
1690
|
element: /* @__PURE__ */ jsx(EffectiveExternalLayout, { children: /* @__PURE__ */ jsx(ExtComponent, {}) }),
|
|
1597
1691
|
loader: async () => ({
|
|
1598
|
-
path,
|
|
1599
|
-
locale
|
|
1692
|
+
path: localePath,
|
|
1693
|
+
locale
|
|
1600
1694
|
}),
|
|
1601
|
-
getStaticPaths: () => [
|
|
1602
|
-
});
|
|
1603
|
-
if (config.i18n) Object.keys(config.i18n.locales).forEach((locale) => {
|
|
1604
|
-
const localePath = `/${locale}${rawPath === "/" ? "" : rawPath}`;
|
|
1605
|
-
if (!children.find((r) => r.path === localePath)) {
|
|
1606
|
-
externalMetadata.push({
|
|
1607
|
-
path: localePath,
|
|
1608
|
-
locale,
|
|
1609
|
-
title: rawPath,
|
|
1610
|
-
filePath: "",
|
|
1611
|
-
headings: []
|
|
1612
|
-
});
|
|
1613
|
-
children.push({
|
|
1614
|
-
path: localePath,
|
|
1615
|
-
element: /* @__PURE__ */ jsx(EffectiveExternalLayout, { children: /* @__PURE__ */ jsx(ExtComponent, {}) }),
|
|
1616
|
-
loader: async () => ({
|
|
1617
|
-
path: localePath,
|
|
1618
|
-
locale
|
|
1619
|
-
}),
|
|
1620
|
-
getStaticPaths: () => [localePath]
|
|
1621
|
-
});
|
|
1622
|
-
}
|
|
1695
|
+
getStaticPaths: () => [localePath]
|
|
1623
1696
|
});
|
|
1624
|
-
}
|
|
1697
|
+
});
|
|
1625
1698
|
});
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1699
|
+
return {
|
|
1700
|
+
children,
|
|
1701
|
+
metadata
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
//#endregion
|
|
1706
|
+
//#region src/client/ssg/create-routes.collection.tsx
|
|
1707
|
+
function DefaultCollectionList() {
|
|
1708
|
+
const data = useLoaderData();
|
|
1709
|
+
if (!data || !data.posts) return null;
|
|
1710
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1711
|
+
className: "py-8 max-w-2xl mx-auto px-4",
|
|
1712
|
+
children: [
|
|
1713
|
+
/* @__PURE__ */ jsx("h1", {
|
|
1714
|
+
className: "text-3xl font-bold mb-6 capitalize",
|
|
1715
|
+
children: data.collection
|
|
1716
|
+
}),
|
|
1717
|
+
/* @__PURE__ */ jsx("div", {
|
|
1718
|
+
className: "space-y-6",
|
|
1719
|
+
children: data.posts.map((post) => /* @__PURE__ */ jsxs("article", {
|
|
1720
|
+
className: "border-b border-subtle pb-4",
|
|
1721
|
+
children: [
|
|
1722
|
+
/* @__PURE__ */ jsx("h2", {
|
|
1723
|
+
className: "text-xl font-semibold mb-2",
|
|
1724
|
+
children: /* @__PURE__ */ jsx(Link, {
|
|
1725
|
+
to: post.path,
|
|
1726
|
+
className: "text-primary-600 hover:underline",
|
|
1727
|
+
children: post.title
|
|
1728
|
+
})
|
|
1729
|
+
}),
|
|
1730
|
+
post.date && /* @__PURE__ */ jsx("time", {
|
|
1731
|
+
className: "text-xs text-muted block mb-2",
|
|
1732
|
+
children: new Date(post.date).toLocaleDateString()
|
|
1733
|
+
}),
|
|
1734
|
+
post.excerpt && /* @__PURE__ */ jsx("p", {
|
|
1735
|
+
className: "text-sm text-body",
|
|
1736
|
+
children: post.excerpt
|
|
1737
|
+
})
|
|
1738
|
+
]
|
|
1739
|
+
}, post.path))
|
|
1740
|
+
}),
|
|
1741
|
+
data.totalPages > 1 && /* @__PURE__ */ jsxs("div", {
|
|
1742
|
+
className: "mt-8 flex gap-4 text-sm",
|
|
1743
|
+
children: [
|
|
1744
|
+
data.currentPage > 1 && /* @__PURE__ */ jsx(Link, {
|
|
1745
|
+
to: data.currentPage === 2 ? `/${data.collection}` : `/${data.collection}/page/${data.currentPage - 1}`,
|
|
1746
|
+
className: "text-primary-600 hover:underline",
|
|
1747
|
+
children: "Previous"
|
|
1748
|
+
}),
|
|
1749
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1750
|
+
"Page ",
|
|
1751
|
+
data.currentPage,
|
|
1752
|
+
" of ",
|
|
1753
|
+
data.totalPages
|
|
1754
|
+
] }),
|
|
1755
|
+
data.currentPage < data.totalPages && /* @__PURE__ */ jsx(Link, {
|
|
1756
|
+
to: `/${data.collection}/page/${data.currentPage + 1}`,
|
|
1757
|
+
className: "text-primary-600 hover:underline",
|
|
1758
|
+
children: "Next"
|
|
1759
|
+
})
|
|
1760
|
+
]
|
|
1761
|
+
})
|
|
1762
|
+
]
|
|
1629
1763
|
});
|
|
1764
|
+
}
|
|
1765
|
+
function buildCollectionRoutes(options) {
|
|
1766
|
+
const { routesData, collectionsData, collectionLayouts, collectionLists, collectionPosts, config, mdxModules, components } = options;
|
|
1767
|
+
const postsPerPage = options.postsPerPage ?? config.collections?.postsPerPage ?? 10;
|
|
1768
|
+
const children = [];
|
|
1769
|
+
const metadata = [];
|
|
1770
|
+
const collectionsMap = /* @__PURE__ */ new Map();
|
|
1771
|
+
for (const r of routesData) if (r.collection) {
|
|
1772
|
+
if (!collectionsMap.has(r.collection)) collectionsMap.set(r.collection, []);
|
|
1773
|
+
collectionsMap.get(r.collection).push(r);
|
|
1774
|
+
}
|
|
1775
|
+
const moduleMap = buildModuleMap(mdxModules);
|
|
1776
|
+
const mdxModuleKeys = Object.keys(mdxModules);
|
|
1777
|
+
const isLazy = mdxModuleKeys.length > 0 && typeof mdxModules[mdxModuleKeys[0]] === "function";
|
|
1778
|
+
for (const [colName, colRoutes] of collectionsMap) {
|
|
1779
|
+
const colBase = `/${colName}`;
|
|
1780
|
+
colRoutes.sort((a, b) => {
|
|
1781
|
+
const da = a.date ? new Date(a.date).getTime() : 0;
|
|
1782
|
+
return (b.date ? new Date(b.date).getTime() : 0) - da;
|
|
1783
|
+
});
|
|
1784
|
+
const colChildren = [];
|
|
1785
|
+
for (const route of colRoutes) {
|
|
1786
|
+
const normalizedFilePath = route.filePath.replace(/\\/g, "/");
|
|
1787
|
+
const moduleKey = moduleMap.get(normalizedFilePath);
|
|
1788
|
+
const moduleLoader = moduleKey ? mdxModules[moduleKey] : null;
|
|
1789
|
+
const subPath = route.path.startsWith(colBase + "/") ? route.path.slice(colBase.length + 1) : route.path.replace(colBase, "") || "";
|
|
1790
|
+
const routeWithCollection = {
|
|
1791
|
+
...route,
|
|
1792
|
+
collection: colName
|
|
1793
|
+
};
|
|
1794
|
+
const postComponent = collectionPosts?.[colName];
|
|
1795
|
+
const routeRecord = {
|
|
1796
|
+
path: subPath,
|
|
1797
|
+
loader: async () => ({
|
|
1798
|
+
route: routeWithCollection,
|
|
1799
|
+
headings: route.headings || [],
|
|
1800
|
+
collection: colName,
|
|
1801
|
+
path: subPath,
|
|
1802
|
+
frontmatter: {
|
|
1803
|
+
title: route.title,
|
|
1804
|
+
description: route.description || "",
|
|
1805
|
+
...route.frontmatter || {}
|
|
1806
|
+
},
|
|
1807
|
+
filePath: route.filePath,
|
|
1808
|
+
locale: route.locale,
|
|
1809
|
+
version: route.version,
|
|
1810
|
+
date: route.date,
|
|
1811
|
+
lastUpdated: route.lastUpdated
|
|
1812
|
+
}),
|
|
1813
|
+
getStaticPaths: () => [subPath || "."]
|
|
1814
|
+
};
|
|
1815
|
+
if (isLazy && moduleLoader) routeRecord.lazy = async () => {
|
|
1816
|
+
const mod = await resolveModuleLoader(moduleLoader);
|
|
1817
|
+
return { Component: function LoadedCollectionMdxRoute() {
|
|
1818
|
+
return /* @__PURE__ */ jsx(EagerMdxElement, {
|
|
1819
|
+
moduleKey,
|
|
1820
|
+
moduleLoader: mod,
|
|
1821
|
+
route,
|
|
1822
|
+
components,
|
|
1823
|
+
collectionPostComponent: postComponent
|
|
1824
|
+
}, moduleKey || subPath);
|
|
1825
|
+
} };
|
|
1826
|
+
};
|
|
1827
|
+
else routeRecord.element = /* @__PURE__ */ jsx(EagerMdxElement, {
|
|
1828
|
+
moduleKey,
|
|
1829
|
+
moduleLoader,
|
|
1830
|
+
route,
|
|
1831
|
+
components,
|
|
1832
|
+
collectionPostComponent: postComponent
|
|
1833
|
+
}, moduleKey || subPath);
|
|
1834
|
+
colChildren.push(routeRecord);
|
|
1835
|
+
metadata.push(route);
|
|
1836
|
+
}
|
|
1837
|
+
const totalPages = Math.ceil(colRoutes.length / postsPerPage);
|
|
1838
|
+
const paginatedPosts = colRoutes.map((r) => ({
|
|
1839
|
+
path: r.path,
|
|
1840
|
+
title: r.title,
|
|
1841
|
+
date: r.date,
|
|
1842
|
+
excerpt: r.excerpt,
|
|
1843
|
+
tags: r.tags,
|
|
1844
|
+
author: r.author,
|
|
1845
|
+
coverImage: r.coverImage,
|
|
1846
|
+
filePath: r.filePath,
|
|
1847
|
+
frontmatter: r.frontmatter
|
|
1848
|
+
}));
|
|
1849
|
+
const ListElement = collectionLists?.[colName] || DefaultCollectionList;
|
|
1850
|
+
colChildren.unshift({
|
|
1851
|
+
index: true,
|
|
1852
|
+
element: /* @__PURE__ */ jsx(ListElement, {}),
|
|
1853
|
+
loader: async () => ({
|
|
1854
|
+
posts: paginatedPosts.slice(0, postsPerPage),
|
|
1855
|
+
totalPages,
|
|
1856
|
+
currentPage: 1,
|
|
1857
|
+
collection: colName
|
|
1858
|
+
}),
|
|
1859
|
+
getStaticPaths: () => []
|
|
1860
|
+
});
|
|
1861
|
+
for (let p = 2; p <= totalPages; p++) colChildren.push({
|
|
1862
|
+
path: `page/${p}`,
|
|
1863
|
+
element: /* @__PURE__ */ jsx(ListElement, {}),
|
|
1864
|
+
loader: async () => ({
|
|
1865
|
+
posts: paginatedPosts.slice((p - 1) * postsPerPage, p * postsPerPage),
|
|
1866
|
+
totalPages,
|
|
1867
|
+
currentPage: p,
|
|
1868
|
+
collection: colName
|
|
1869
|
+
}),
|
|
1870
|
+
getStaticPaths: () => [`page/${p}`]
|
|
1871
|
+
});
|
|
1872
|
+
const blogLayoutRoute = {
|
|
1873
|
+
path: colBase,
|
|
1874
|
+
element: /* @__PURE__ */ jsx(collectionLayouts?.[colName] || DocsLayout, { collectionsData: collectionsData || {} }),
|
|
1875
|
+
children: colChildren
|
|
1876
|
+
};
|
|
1877
|
+
children.push(blogLayoutRoute);
|
|
1878
|
+
}
|
|
1879
|
+
return {
|
|
1880
|
+
children,
|
|
1881
|
+
metadata
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
//#endregion
|
|
1886
|
+
//#region src/client/ssg/create-routes.tsx
|
|
1887
|
+
function createRoutes(options) {
|
|
1888
|
+
const { config, components, externalLayout } = options;
|
|
1889
|
+
const EffectiveExternalLayout = externalLayout || (({ children }) => /* @__PURE__ */ jsx(Fragment, { children }));
|
|
1890
|
+
const baseDocsPath = (config.base || "/docs").replace(/\/$/, "") || "/";
|
|
1891
|
+
const { routes: docRoutes, metadata: docMetadata } = buildDocRoutes(options);
|
|
1892
|
+
const externalRoutes = buildExternalRoutes(options);
|
|
1893
|
+
const collectionRoutes = buildCollectionRoutes(options);
|
|
1894
|
+
const children = [
|
|
1895
|
+
{
|
|
1896
|
+
path: baseDocsPath,
|
|
1897
|
+
element: /* @__PURE__ */ jsx(DocsLayout, {}),
|
|
1898
|
+
children: docRoutes
|
|
1899
|
+
},
|
|
1900
|
+
...externalRoutes.children,
|
|
1901
|
+
...collectionRoutes.children,
|
|
1902
|
+
{
|
|
1903
|
+
path: "*",
|
|
1904
|
+
element: /* @__PURE__ */ jsx(EffectiveExternalLayout, { children: /* @__PURE__ */ jsx(NotFoundWrapper, {}) })
|
|
1905
|
+
}
|
|
1906
|
+
];
|
|
1630
1907
|
return [{
|
|
1631
1908
|
element: /* @__PURE__ */ jsx(BoltdocsShell, {
|
|
1632
1909
|
config,
|
|
1633
|
-
routes: [
|
|
1910
|
+
routes: [
|
|
1911
|
+
...docMetadata,
|
|
1912
|
+
...externalRoutes.metadata,
|
|
1913
|
+
...collectionRoutes.metadata
|
|
1914
|
+
],
|
|
1634
1915
|
components
|
|
1635
1916
|
}),
|
|
1636
1917
|
children
|
|
@@ -1816,29 +2097,40 @@ function useTrackEvent() {
|
|
|
1816
2097
|
}
|
|
1817
2098
|
|
|
1818
2099
|
//#endregion
|
|
1819
|
-
//#region src/client/
|
|
2100
|
+
//#region src/client/hooks/use-headings.ts
|
|
1820
2101
|
/**
|
|
1821
|
-
*
|
|
1822
|
-
*
|
|
2102
|
+
* Returns the headings of the current page, extracted from the route loader data.
|
|
2103
|
+
* Useful for building custom Tables of Contents or jumping to sections.
|
|
2104
|
+
*
|
|
2105
|
+
* @returns An array of heading objects with level, text, and id.
|
|
1823
2106
|
*/
|
|
2107
|
+
function useHeadings() {
|
|
2108
|
+
const matches = useMatches();
|
|
2109
|
+
return useMemo(() => {
|
|
2110
|
+
return (matches[matches.length - 1]?.data)?.headings || [];
|
|
2111
|
+
}, [matches]);
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
//#endregion
|
|
2115
|
+
//#region src/client/components/docs-layout-default.tsx
|
|
1824
2116
|
function DocsLayoutComponent({ children }) {
|
|
1825
|
-
const { routes: filteredRoutes, currentRoute } = useRoutes();
|
|
2117
|
+
const { routes: filteredRoutes, currentRoute, isCollectionPage } = useRoutes();
|
|
1826
2118
|
const config = useConfig();
|
|
1827
|
-
return /* @__PURE__ */ jsxs(DocsLayout$
|
|
2119
|
+
return /* @__PURE__ */ jsxs(DocsLayout$1, {
|
|
1828
2120
|
className: "selection:bg-primary-500/10 selection:text-primary-500",
|
|
1829
|
-
children: [/* @__PURE__ */ jsx(Navbar, {}), /* @__PURE__ */ jsxs(DocsLayout$
|
|
2121
|
+
children: [/* @__PURE__ */ jsx(Navbar, {}), /* @__PURE__ */ jsxs(DocsLayout$1.Body, {
|
|
1830
2122
|
className: "bg-main",
|
|
1831
2123
|
children: [
|
|
1832
|
-
/* @__PURE__ */ jsx(Sidebar, {
|
|
2124
|
+
!isCollectionPage && /* @__PURE__ */ jsx(Sidebar, {
|
|
1833
2125
|
routes: filteredRoutes || [],
|
|
1834
2126
|
config
|
|
1835
2127
|
}),
|
|
1836
|
-
/* @__PURE__ */ jsx(DocsLayout$
|
|
2128
|
+
/* @__PURE__ */ jsx(DocsLayout$1.Content, {
|
|
1837
2129
|
className: "animate-in fade-in duration-500 scroll-smooth",
|
|
1838
|
-
children: /* @__PURE__ */ jsxs(DocsLayout$
|
|
1839
|
-
className: "max-w-3xl sm:max-w-4xl lg:max-w-
|
|
2130
|
+
children: /* @__PURE__ */ jsxs(DocsLayout$1.ContentMdx, {
|
|
2131
|
+
className: "max-w-3xl sm:max-w-4xl lg:max-w-5xl px-4 sm:px-6 pt-8 pb-24",
|
|
1840
2132
|
children: [
|
|
1841
|
-
/* @__PURE__ */ jsxs(DocsLayout$
|
|
2133
|
+
!isCollectionPage && /* @__PURE__ */ jsxs(DocsLayout$1.Header, { children: [
|
|
1842
2134
|
/* @__PURE__ */ jsxs("div", {
|
|
1843
2135
|
className: "mb-4 border-b border-subtle pb-4 flex flex-wrap items-center justify-between gap-3",
|
|
1844
2136
|
children: [/* @__PURE__ */ jsx(Breadcrumbs, {}), /* @__PURE__ */ jsx(CopyMarkdown, {
|
|
@@ -1859,7 +2151,7 @@ function DocsLayoutComponent({ children }) {
|
|
|
1859
2151
|
className: "prose prose-neutral dark:prose-invert max-w-none",
|
|
1860
2152
|
children
|
|
1861
2153
|
}) }),
|
|
1862
|
-
/* @__PURE__ */ jsx(DocsLayout$
|
|
2154
|
+
/* @__PURE__ */ jsx(DocsLayout$1.Footer, { children: !isCollectionPage && /* @__PURE__ */ jsx(PageNav, {}) })
|
|
1863
2155
|
]
|
|
1864
2156
|
})
|
|
1865
2157
|
}),
|
|
@@ -1873,13 +2165,55 @@ function DocsLayoutComponent({ children }) {
|
|
|
1873
2165
|
})]
|
|
1874
2166
|
});
|
|
1875
2167
|
}
|
|
1876
|
-
const DocsLayout = Object.assign(DocsLayoutComponent, {
|
|
1877
|
-
Body: DocsLayout$2.Body,
|
|
1878
|
-
Content: DocsLayout$2.Content,
|
|
1879
|
-
ContentMdx: DocsLayout$2.ContentMdx,
|
|
1880
|
-
Header: DocsLayout$2.Header,
|
|
1881
|
-
Footer: DocsLayout$2.Footer
|
|
1882
|
-
});
|
|
1883
2168
|
|
|
1884
2169
|
//#endregion
|
|
1885
|
-
|
|
2170
|
+
//#region src/client/collections/hooks.ts
|
|
2171
|
+
/**
|
|
2172
|
+
* Returns the posts of a collection.
|
|
2173
|
+
* @param collection - The name of the collection.
|
|
2174
|
+
* @returns The posts of the collection.
|
|
2175
|
+
*/
|
|
2176
|
+
function usePosts(collection) {
|
|
2177
|
+
return useCollectionsData()[collection] || [];
|
|
2178
|
+
}
|
|
2179
|
+
/**
|
|
2180
|
+
* Returns a post by its slug.
|
|
2181
|
+
* @param collection - The name of the collection.
|
|
2182
|
+
* @param slug - The slug of the post.
|
|
2183
|
+
* @returns The post with the given slug.
|
|
2184
|
+
*/
|
|
2185
|
+
function usePost(collection, slug) {
|
|
2186
|
+
const posts = usePosts(collection);
|
|
2187
|
+
return useMemo(() => posts.find((p) => p.path === `/${collection}/${slug}` || p.path.endsWith(`/${slug}`) || p.path === slug), [
|
|
2188
|
+
posts,
|
|
2189
|
+
collection,
|
|
2190
|
+
slug
|
|
2191
|
+
]);
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Returns the recent posts of a collection.
|
|
2195
|
+
* @param collection - The name of the collection.
|
|
2196
|
+
* @param count - The number of recent posts to return.
|
|
2197
|
+
* @returns The recent posts of the collection.
|
|
2198
|
+
*/
|
|
2199
|
+
function useRecentPosts(collection, count = 5) {
|
|
2200
|
+
const posts = usePosts(collection);
|
|
2201
|
+
return useMemo(() => posts.slice(0, count), [posts, count]);
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
//#endregion
|
|
2205
|
+
//#region src/client/utils/react-to-text.ts
|
|
2206
|
+
const reactToText = (node, resolvers) => {
|
|
2207
|
+
if (node == null || typeof node === "boolean") return "";
|
|
2208
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
2209
|
+
if (Array.isArray(node)) return node.map((n) => reactToText(n, resolvers)).join("");
|
|
2210
|
+
if (isValidElement(node)) {
|
|
2211
|
+
const resolver = resolvers?.get(node.type);
|
|
2212
|
+
if (resolver) return resolver(node.props);
|
|
2213
|
+
return reactToText(node.props.children, resolvers);
|
|
2214
|
+
}
|
|
2215
|
+
return "";
|
|
2216
|
+
};
|
|
2217
|
+
|
|
2218
|
+
//#endregion
|
|
2219
|
+
export { Banner, BoltdocsShell, Breadcrumbs, CollectionsContext, CopyMarkdown, DocsLayoutComponent as DocsLayout, ErrorBoundary, MdxPage, Navbar, NotFound, OnThisPage, PageNav, SearchDialog, Sidebar, ViteReactSSG, cn, copyToClipboard, createRoutes, getStarsRepo, getTranslated, reactToText, useAnalytics, useBreadcrumbs, useConfig, useHeadings, useI18n, useLocalizedTo, useLocation, useMdxComponents, useMergedComponents, useNavbar, usePageNav, usePost, usePosts, useRecentPosts, useRoutes, useSearch, useSearchHighlight, useSidebar, useTabs, useTheme, useTrackEvent, useTrackPageView, useUI, useVersion };
|