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