@docubook/flame 2.0.2 → 2.1.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/.docu/components/Context.tsx +6 -5
- package/.docu/components/DocsLayout.tsx +7 -4
- package/.docu/components/Menu.tsx +10 -9
- package/.docu/components/Navbar.tsx +24 -22
- package/.docu/components/Pagination.tsx +3 -2
- package/.docu/components/Search.tsx +6 -1
- package/.docu/components/Sidebar.tsx +22 -21
- package/.docu/components/Sublink.tsx +3 -3
- package/.docu/lib/build.deno.js +1 -1
- package/.docu/lib/{build.impl-CA7XPLz0.js → build.impl-DK485Nx1.js} +60 -31
- package/.docu/lib/build.impl-DK485Nx1.js.map +1 -0
- package/.docu/lib/build.impl-Dmybgcj2.js +2 -0
- package/.docu/lib/build.node.js +1 -1
- package/.docu/lib/clean.js +1 -1
- package/.docu/lib/deploy.deno.js +1 -1
- package/.docu/lib/deploy.node.js +1 -1
- package/.docu/lib/{deploy.shared-DjD3qs7t.js → deploy.shared-BW2KXFXs.js} +27 -8
- package/.docu/lib/deploy.shared-BW2KXFXs.js.map +1 -0
- package/.docu/lib/{html.shared-CsEFmy_Y.js → html.shared-RPCM1y5Q.js} +264 -73
- package/.docu/lib/html.shared-RPCM1y5Q.js.map +1 -0
- package/.docu/lib/{logger-_e2TNmEq.js → logger-DYFD47f8.js} +3 -3
- package/.docu/lib/{logger-_e2TNmEq.js.map → logger-DYFD47f8.js.map} +1 -1
- package/.docu/lib/paths-CHXABfXa.js +332 -0
- package/.docu/lib/paths-CHXABfXa.js.map +1 -0
- package/.docu/lib/preview.deno.js +1 -1
- package/.docu/lib/{preview.impl-DiTu2Coo.js → preview.impl-DMXVsGs0.js} +4 -4
- package/.docu/lib/preview.impl-DMXVsGs0.js.map +1 -0
- package/.docu/lib/preview.node.js +1 -1
- package/.docu/lib/{utils-B_CoyKie.js → server-utils-BYWB7A6T.js} +3 -21
- package/.docu/lib/server-utils-BYWB7A6T.js.map +1 -0
- package/.docu/lib/server.deno.js +1 -1
- package/.docu/lib/{server.impl-DPBnKdIh.js → server.impl-DcyZhPA_.js} +24 -19
- package/.docu/lib/server.impl-DcyZhPA_.js.map +1 -0
- package/.docu/lib/server.node.js +1 -1
- package/.docu/node/base-path.ts +306 -0
- package/.docu/node/build.impl.ts +50 -17
- package/.docu/node/build.ts +50 -17
- package/.docu/node/cache-key.ts +92 -4
- package/.docu/node/client-routes.ts +16 -1
- package/.docu/node/deploy.shared.ts +51 -15
- package/.docu/node/deploy.ts +7 -3
- package/.docu/node/html.shared.ts +33 -3
- package/.docu/node/html.ts +18 -3
- package/.docu/node/hydrate.node.ts +6 -0
- package/.docu/node/hydrate.ts +16 -1
- package/.docu/node/mdx.ts +102 -23
- package/.docu/node/paths.ts +115 -0
- package/.docu/node/preview.impl.ts +1 -1
- package/.docu/node/preview.ts +1 -1
- package/.docu/node/search-indexer.ts +20 -3
- package/.docu/node/seo.ts +41 -7
- package/.docu/node/server-routes.ts +34 -11
- package/.docu/node/server-utils.ts +152 -0
- package/.docu/node/server.impl.ts +22 -12
- package/.docu/node/server.ts +23 -27
- package/.docu/node/types.ts +13 -0
- package/.docu/node/utils.ts +56 -149
- package/.docu/pages/404.tsx +2 -1
- package/.docu/pages/index.tsx +6 -13
- package/bin/cli.js +5 -0
- package/docu.schema.json +10 -1
- package/package.json +5 -5
- package/template/docu.json +1 -0
- package/.docu/lib/build.impl-C97QWe1I.js +0 -2
- package/.docu/lib/build.impl-CA7XPLz0.js.map +0 -1
- package/.docu/lib/deploy.shared-DjD3qs7t.js.map +0 -1
- package/.docu/lib/html.shared-CsEFmy_Y.js.map +0 -1
- package/.docu/lib/paths-Cbz-dj4s.js +0 -72
- package/.docu/lib/paths-Cbz-dj4s.js.map +0 -1
- package/.docu/lib/preview.impl-DiTu2Coo.js.map +0 -1
- package/.docu/lib/server.impl-DPBnKdIh.js.map +0 -1
- package/.docu/lib/utils-B_CoyKie.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.shared-RPCM1y5Q.js","names":[],"sources":["../node/plugin-loader.ts","../node/plugin-builder.ts","../node/cache-key.ts","../node/fs-scanner.ts","../node/hydrate.ts","../node/hydrate.node.ts","../node/git.ts","../node/mdx.ts","../node/utils.ts","../node/search-indexer.ts","../node/sentry.ts","../components/Breadcrumb.tsx","../node/route.ts","../node/client-routes.ts","../components/Pagination.tsx","../components/Typography.tsx","../node/helpers.ts","../components/EditWith.tsx","../components/Social.tsx","../components/Footer.tsx","../components/ScrollTo.tsx","../components/Toc.tsx","../pages/docs/[[...slug]].tsx","../components/home/BackgroundBlobs.tsx","../components/Lucide.tsx","../components/home/Hero.tsx","../components/home/Features.tsx","../pages/404.tsx","../components/Theme.tsx","../pages/index.tsx","../components/Anchor.tsx","../components/Sublink.tsx","../components/SidebarGroupHeader.tsx","../components/Menu.tsx","../components/DocsLayout.tsx","../node/escapeHtml.ts","../node/html.shared.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { PROJECT_ROOT } from \"./paths\";\nimport type { DocuBookPlugin, PluginEntry } from \"./plugin\";\n\nconst NPM_PACKAGE_RE = /^(?:@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\n/**\n * Resolve a plugin specifier to an absolute path or npm package name.\n *\n * Resolution rules:\n * 1. Relative path (starts with `.`) → resolve from project root, guard traversal\n * 2. Absolute path (starts with `/`) → guard traversal\n * 3. Anything else → validate as npm package name, then pass to Bun's import\n *\n * Path traversal protection:\n * - All file-system paths (relative & absolute) must resolve within PROJECT_ROOT.\n * - This prevents `../../sensitive-file` or `/etc/passwd` from being imported.\n */\n/** @internal Exported for testing only. */\nexport function resolveSpecifier(specifier: string): string {\n let resolved: string;\n\n if (specifier.startsWith(\".\")) {\n // Relative path → resolve from project root\n resolved = resolve(PROJECT_ROOT, specifier);\n } else if (specifier.startsWith(\"/\")) {\n // Absolute path → use as-is\n resolved = specifier;\n } else {\n // npm package name → validate format, then handled by Bun's import\n if (!NPM_PACKAGE_RE.test(specifier)) {\n throw new Error(\n `[plugin-loader] Invalid plugin specifier \"${specifier}\": must be a valid npm package name, relative path, or absolute path`\n );\n }\n return specifier;\n }\n\n // Path traversal guard: resolved path must stay within PROJECT_ROOT\n const root = PROJECT_ROOT.endsWith(\"/\") ? PROJECT_ROOT : PROJECT_ROOT + \"/\";\n if (!resolved.startsWith(root)) {\n throw new Error(\n `[plugin-loader] Path traversal blocked: \"${specifier}\" resolves outside project root`\n );\n }\n\n return resolved;\n}\n\n/**\n * Load and instantiate all plugins from a config entries array.\n *\n * @param entries - Array of plugin entries from `docu.json`.\n * Each entry is either:\n * - a `string` (plugin specifier, no options)\n * - a `[string, object]` tuple (plugin specifier + factory options)\n * @returns Array of resolved `DocuBookPlugin` instances.\n *\n * @throws If a plugin specifier cannot be imported.\n * @throws If a plugin's default export lacks a `name` property.\n *\n * @example\n * const plugins = await loadPlugins([\n * \"@docubook/plugin-sitemap\",\n * [\"@docubook/plugin-analytics\", { id: \"G-XXXXXXX\" }],\n * \"./plugins/local-reading-time\",\n * ]);\n */\nexport async function loadPlugins(entries: PluginEntry[] = []): Promise<DocuBookPlugin[]> {\n const plugins: DocuBookPlugin[] = [];\n\n for (const entry of entries) {\n const [specifier, options] = Array.isArray(entry) ? entry : [entry, undefined];\n const resolved = resolveSpecifier(specifier);\n\n let mod: Record<string, unknown>;\n try {\n mod = await import(resolved);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`[plugin-loader] Failed to import plugin \"${specifier}\": ${message}`, {\n cause: err,\n });\n }\n\n const exported = mod.default as unknown;\n\n let plugin: DocuBookPlugin;\n\n if (typeof exported === \"function\") {\n // Factory pattern: exported function receives options, returns DocuBookPlugin\n try {\n plugin = (exported as (opts?: Record<string, unknown>) => DocuBookPlugin)(options);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `[plugin-loader] Plugin factory \"${specifier}\" threw during initialization: ${message}`,\n { cause: err }\n );\n }\n } else if (exported && typeof exported === \"object\") {\n // Simple pattern: exported object is (or duck-types as) DocuBookPlugin\n plugin = exported as DocuBookPlugin;\n } else {\n throw new Error(\n `[plugin-loader] Plugin \"${specifier}\" must export a default function or object. Got: ${typeof exported}`\n );\n }\n\n if (!plugin.name || typeof plugin.name !== \"string\") {\n throw new Error(\n `[plugin-loader] Plugin \"${specifier}\" must have a valid 'name' property (string). Got: ${typeof plugin.name}`\n );\n }\n\n if (typeof plugin.setup !== \"function\") {\n throw new Error(\n `[plugin-loader] Plugin \"${specifier}\" (name: \"${plugin.name}\") must have a 'setup(build)' function.`\n );\n }\n\n plugins.push(plugin);\n }\n\n return plugins;\n}\n","import type { Pluggable } from \"unified\";\nimport type {\n BuildEndContext,\n DevServerContext,\n DocuConfig,\n PageContext,\n PageMeta,\n PluginBuilder,\n} from \"./plugin\";\n\ntype Awaitable<T> = T | Promise<T>;\n\ninterface OnLoadHandler {\n filter: RegExp;\n namespace?: string;\n fn: (args: {\n path: string;\n content: string;\n }) => Awaitable<{ contents?: string; loader?: \"js\" | \"ts\" | \"mdx\" } | void>;\n}\n\nexport class BuildPluginBuilder implements PluginBuilder {\n readonly config: DocuConfig;\n\n private _handleRequest: Array<\n (req: Request, context: DevServerContext) => Awaitable<Response | void>\n > = [];\n private _injectBody: Array<(context: PageContext) => string | string[]> = [];\n private _injectHead: Array<(context: PageContext) => string | string[]> = [];\n private _onEnd: Array<\n (config: DocuConfig, pages: PageMeta[], context: BuildEndContext) => Awaitable<void>\n > = [];\n private _onLoad: OnLoadHandler[] = [];\n private _onStart: Array<(config: DocuConfig) => Awaitable<void>> = [];\n private _rehypePlugins: Array<() => Pluggable[]> = [];\n private _remarkPlugins: Array<() => Pluggable[]> = [];\n private _transformFrontmatter: Array<\n (\n frontmatter: Record<string, unknown>,\n context: Pick<PageContext, \"slug\" | \"filePath\" | \"content\">\n ) => Awaitable<Record<string, unknown> | void>\n > = [];\n private _transformHtml: Array<(html: string, context: PageContext) => Awaitable<string>> = [];\n\n constructor(config: DocuConfig) {\n this.config = config;\n }\n\n /**\n * Collect and deduplicate all `<body>` injection snippets from registered plugins.\n * Each callback is executed in registration order; plugin errors are wrapped\n * with a descriptive message.\n *\n * @param context - Current page context passed to each injectBody callback.\n * @returns Deduplicated array of HTML strings to inject before `</body>`.\n * @throws Error if any injectBody callback throws — wraps original error as cause.\n */\n collectBody(context: PageContext): string[] {\n const items: string[] = [];\n for (const cb of this._injectBody) {\n try {\n const result = cb(context);\n if (result) {\n this.collectItems(items, result, \"injectBody\");\n }\n } catch (err) {\n throw new Error(\n `[plugin] injectBody callback failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err }\n );\n }\n }\n return [...new Set(items)];\n }\n\n /**\n * Collect and deduplicate all `<head>` injection snippets from registered plugins.\n * Each callback is executed in registration order; plugin errors are wrapped\n * with a descriptive message.\n *\n * @param context - Current page context passed to each injectHead callback.\n * @returns Deduplicated array of HTML strings to inject before `</head>`.\n * @throws Error if any injectHead callback throws — wraps original error as cause.\n */\n collectHead(context: PageContext): string[] {\n const items: string[] = [];\n for (const cb of this._injectHead) {\n try {\n const result = cb(context);\n if (result) {\n this.collectItems(items, result, \"injectHead\");\n }\n } catch (err) {\n throw new Error(\n `[plugin] injectHead callback failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err }\n );\n }\n }\n return [...new Set(items)];\n }\n\n /**\n * Collect all rehype plugin arrays from registered rehypePlugins callbacks.\n * Results from all plugins are flattened into a single array.\n *\n * @returns Flattened array of rehype plugin instances applied after default set.\n * @throws Error if any rehypePlugins callback throws — wraps original error as cause.\n */\n collectRehypePlugins(): Pluggable[] {\n const plugins: Pluggable[] = [];\n for (const cb of this._rehypePlugins) {\n try {\n plugins.push(...cb());\n } catch (err) {\n throw new Error(\n `[plugin] rehypePlugins callback failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err }\n );\n }\n }\n return plugins;\n }\n\n /**\n * Collect all remark plugin arrays from registered remarkPlugins callbacks.\n * Results from all plugins are flattened into a single array.\n *\n * @returns Flattened array of remark plugin instances applied after default set.\n * @throws Error if any remarkPlugins callback throws — wraps original error as cause.\n */\n collectRemarkPlugins(): Pluggable[] {\n const plugins: Pluggable[] = [];\n for (const cb of this._remarkPlugins) {\n try {\n plugins.push(...cb());\n } catch (err) {\n throw new Error(\n `[plugin] remarkPlugins callback failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err }\n );\n }\n }\n return plugins;\n }\n\n /**\n * Register a callback to intercept incoming requests during development.\n * The **first** callback to return a `Response` short-circuits all subsequent handlers.\n * Errors inside callbacks are caught and logged — execution continues to next handler.\n *\n * @param callback - Receives the Request and dev server context. Return Response or void.\n *\n * @example\n * build.handleRequest((req, ctx) => {\n * if (new URL(req.url).pathname === \"/api/status\") {\n * return new Response(JSON.stringify({ ok: true }), {\n * headers: { \"Content-Type\": \"application/json\" },\n * });\n * }\n * });\n */\n handleRequest(\n callback: (req: Request, context: DevServerContext) => Awaitable<Response | void>\n ): void {\n this._handleRequest.push(callback);\n }\n\n /**\n * Register a callback that returns HTML strings to inject before `</body>`.\n * Results from all plugins are merged, deduplicated, and served via `collectBody()`.\n *\n * @param callback - Returns a single HTML string or an array. Called once per page.\n *\n * @example\n * build.injectBody(() => `<div id=\"chat-widget\"></div>`);\n */\n injectBody(callback: (context: PageContext) => string | string[]): void {\n this._injectBody.push(callback);\n }\n\n /**\n * Register a callback that returns HTML strings to inject inside `<head>`.\n * Results from all plugins are merged, deduplicated, and served via `collectHead()`.\n *\n * @param callback - Returns a single HTML string or an array. Called once per page.\n *\n * @example\n * build.injectHead(() => `<script async src=\"https://cdn.example.com/analytics.js\"></script>`);\n */\n injectHead(callback: (context: PageContext) => string | string[]): void {\n this._injectHead.push(callback);\n }\n\n /**\n * Register a callback to run once after all pages are built.\n * Receives the resolved config, aggregated docs metadata, and final build metadata.\n * Callback errors are logged by `runOnEnd()` and do not stop later callbacks.\n *\n * @param callback - Receives config, page metadata, and emitted assets. May return a Promise.\n *\n * @example\n * build.onEnd(async (config, pages, { outDir }) => {\n * const xml = generateSitemap(pages, config.meta.baseURL);\n * const out = join(outDir, \"sitemap.xml\");\n * // Bun.write on Bun for speed, writeFile on Node/Deno\n * await (typeof Bun !== \"undefined\"\n * ? Bun.write(out, xml)\n * : writeFile(out, xml));\n * });\n */\n onEnd(\n callback: (config: DocuConfig, pages: PageMeta[], context: BuildEndContext) => Awaitable<void>\n ): void {\n this._onEnd.push(callback);\n }\n\n /**\n * Register a callback to transform raw file content before MDX compilation.\n * Filtered by regex against the file's relative path — only the **first** matching\n * handler's result is used.\n * Callback errors are logged by `runOnLoad()` before trying later matching handlers.\n *\n * @param args.filter - RegExp matched against the file's relative path.\n * @param args.namespace - Optional namespace prefix (reserved for future use).\n * @param callback - Receives file path and raw content. Return new contents or void.\n *\n * @example\n * build.onLoad({ filter: /\\.md$/ }, ({ path, content }) => {\n * return { contents: `<!-- preprocessed -->\\n${content}`, loader: \"mdx\" };\n * });\n */\n onLoad(\n args: { filter: RegExp; namespace?: string },\n callback: (args: {\n path: string;\n content: string;\n }) => Awaitable<{ contents?: string; loader?: \"js\" | \"ts\" | \"mdx\" } | void>\n ): void {\n this._onLoad.push({ ...args, fn: callback });\n }\n\n /**\n * Register a callback to run once before the build starts.\n * Receives the resolved DocuConfig for validation or resource initialization.\n * Callback errors are logged by `runOnStart()` and do not stop later callbacks.\n *\n * @param callback - Receives the resolved config. May return a Promise.\n *\n * @example\n * build.onStart((config) => {\n * if (!config.meta.baseURL) throw new Error(\"baseURL required\");\n * });\n */\n onStart(callback: (config: DocuConfig) => Awaitable<void>): void {\n this._onStart.push(callback);\n }\n\n /**\n * Register additional rehype (HTML) plugins for the MDX compilation pipeline.\n * Results from all plugins are merged and applied **after** the default set.\n *\n * @param callback - Returns an array of rehype plugins.\n *\n * @example\n * build.rehypePlugins(() => [require(\"rehype-autolink-headings\")]);\n */\n rehypePlugins(callback: () => Pluggable[]): void {\n this._rehypePlugins.push(callback);\n }\n\n /**\n * Register additional remark (Markdown) plugins for the MDX compilation pipeline.\n * Results from all plugins are merged and applied **after** the default set.\n *\n * @param callback - Returns an array of remark plugins.\n *\n * @example\n * build.remarkPlugins(() => [require(\"remark-custom-heading-id\")]);\n */\n remarkPlugins(callback: () => Pluggable[]): void {\n this._remarkPlugins.push(callback);\n }\n\n /**\n * Execute all registered handleRequest callbacks sequentially.\n * Stops and returns the **first** `Response` returned by any callback.\n * Errors inside individual callbacks are caught and logged — execution\n * continues to the next callback without throwing.\n *\n * @param req - The incoming HTTP Request.\n * @param context - Dev server context (port, hostname).\n * @returns A Response if a callback intercepted the request, or null if none did.\n */\n async runHandleRequest(req: Request, context: DevServerContext): Promise<Response | null> {\n for (let i = 0; i < this._handleRequest.length; i++) {\n try {\n const result = await this._handleRequest[i](req, context);\n if (result instanceof Response) {\n return result;\n }\n } catch (err) {\n console.error(\n `[plugin] handleRequest callback #${i + 1} error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n return null;\n }\n\n /**\n * Execute all registered onEnd callbacks sequentially with the resolved\n * config and aggregated page metadata.\n * Errors inside individual callbacks are caught and logged — execution\n * continues to the next callback without throwing.\n *\n * @param pages - Array of metadata for every built docs page.\n * @param context - Final output directory and page-specific asset manifest.\n */\n async runOnEnd(pages: PageMeta[], context: BuildEndContext): Promise<void> {\n for (let i = 0; i < this._onEnd.length; i++) {\n try {\n await this._onEnd[i](this.config, pages, context);\n } catch (err) {\n console.error(\n `[plugin] onEnd callback #${i + 1} error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n }\n\n /**\n * Execute registered onLoad handlers in registration order against a file.\n * Only the **first** handler whose `filter` regex matches the path and returns\n * a result is applied. If a matching handler throws, the error is logged and\n * subsequent handlers are tried.\n *\n * @param path - Relative path of the file being loaded.\n * @param content - Raw file content.\n * @returns Transformed content if a matching handler returned it, or null.\n */\n async runOnLoad(\n path: string,\n content: string\n ): Promise<{ contents?: string; loader?: \"js\" | \"ts\" | \"mdx\" } | null> {\n for (const handler of this._onLoad) {\n if (handler.filter.test(path)) {\n try {\n const result = await handler.fn({ path, content });\n if (result) return result;\n } catch (err) {\n console.error(\n `[plugin] onLoad handler for filter ${handler.filter} error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n }\n return null;\n }\n\n /**\n * Execute all registered onStart callbacks sequentially.\n * Each callback receives the resolved DocuConfig.\n * Errors inside individual callbacks are caught and logged — execution\n * continues to the next callback without throwing.\n */\n async runOnStart(): Promise<void> {\n for (let i = 0; i < this._onStart.length; i++) {\n try {\n await this._onStart[i](this.config);\n } catch (err) {\n console.error(\n `[plugin] onStart callback #${i + 1} error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n }\n\n /**\n * Execute the transformFrontmatter chain in waterfall pattern.\n * Each callback receives the **previous** callback's return value (or the\n * original frontmatter for the first). Callbacks that return `undefined` or\n * `null` pass the current value through unchanged.\n * Callbacks that return a non-object (string, number, array) are skipped\n * with a console warning — only plain objects are accepted.\n * Errors inside individual callbacks are caught and logged — the current\n * frontmatter passes through unchanged for that step.\n *\n * @param frontmatter - Initial frontmatter object parsed from MDX.\n * @param context - Page context with slug, filePath, and raw content.\n * @returns The final transformed frontmatter object.\n */\n async runTransformFrontmatterChain(\n frontmatter: Record<string, unknown>,\n context: Pick<PageContext, \"slug\" | \"filePath\" | \"content\">\n ): Promise<Record<string, unknown>> {\n let result = frontmatter;\n for (let i = 0; i < this._transformFrontmatter.length; i++) {\n try {\n const next = await this._transformFrontmatter[i](result, context);\n if (next !== undefined && next !== null) {\n if (typeof next === \"object\" && !Array.isArray(next)) {\n result = next;\n } else {\n console.warn(\n `[plugin] transformFrontmatter callback #${i + 1} returned invalid type (expected a plain object), skipping`\n );\n }\n }\n } catch (err) {\n console.error(\n `[plugin] transformFrontmatter callback #${i + 1} error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n return result;\n }\n\n /**\n * Execute the transformHtml chain in pipeline pattern.\n * Each callback receives the **previous** callback's return value (or the\n * original HTML for the first). Every callback **must** return a string.\n * Callbacks returning a non-string (e.g. `undefined`) are skipped with a\n * warning — the current HTML passes through unchanged for that step.\n * Errors inside individual callbacks are caught and logged — the current\n * HTML passes through unchanged for that step.\n *\n * @param html - The initial HTML string.\n * @param context - Full page context (slug, filePath, frontmatter, content, config).\n * @returns The final transformed HTML string.\n */\n async runTransformHtmlChain(html: string, context: PageContext): Promise<string> {\n let result = html;\n for (let i = 0; i < this._transformHtml.length; i++) {\n try {\n const next = await this._transformHtml[i](result, context);\n if (typeof next === \"string\") {\n result = next;\n } else {\n console.warn(\n `[plugin] transformHtml callback #${i + 1} returned invalid type (expected a string), keeping previous HTML`\n );\n }\n } catch (err) {\n console.error(\n `[plugin] transformHtml callback #${i + 1} error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n return result;\n }\n\n /**\n * Register a callback to mutate frontmatter before MDX compilation.\n * Callbacks are chained in a waterfall: the return value of one is passed\n * as input to the next. Return `undefined` to pass through unchanged.\n *\n * **Note:** Only plain objects are accepted as return values. Returning\n * a string, number, or array will be silently skipped with a warning.\n * Plugin authors should validate their return values before returning.\n *\n * @param callback - Receives frontmatter object and page context.\n *\n * @example\n * build.transformFrontmatter((fm, ctx) => {\n * const wordCount = ctx.content!.split(/\\s+/).length;\n * return { ...fm, readingTime: `${Math.ceil(wordCount / 200)} min read` };\n * });\n */\n transformFrontmatter(\n callback: (\n frontmatter: Record<string, unknown>,\n context: Pick<PageContext, \"slug\" | \"filePath\" | \"content\">\n ) => Awaitable<Record<string, unknown> | void>\n ): void {\n this._transformFrontmatter.push(callback);\n }\n\n /**\n * Register a callback to transform the final HTML string per page.\n * This is the **last** hook before the HTML is written to disk.\n * Callbacks are chained in a pipeline: each receives the previous callback's output.\n *\n * @param callback - Receives HTML string and full page context. Must return HTML.\n *\n * @example\n * build.transformHtml((html, ctx) => {\n * return html.replace(/https?:\\/\\/old-domain\\.com\\//g, \"/\");\n * });\n */\n transformHtml(callback: (html: string, context: PageContext) => Awaitable<string>): void {\n this._transformHtml.push(callback);\n }\n\n /**\n * Collect items from a callback result, filtering only valid strings.\n * Non-string items and unexpected types are logged as warnings.\n */\n private collectItems(items: string[], result: string | string[], hookName: string): void {\n if (Array.isArray(result)) {\n for (const item of result) {\n if (typeof item === \"string\") {\n items.push(item);\n } else {\n console.warn(\n `[plugin] ${hookName} callback returned non-string item (got ${typeof item}), skipping`\n );\n }\n }\n } else if (typeof result === \"string\") {\n items.push(result);\n } else {\n console.warn(\n `[plugin] ${hookName} callback returned unexpected type (got ${typeof result}), expected string or string[], skipping`\n );\n }\n }\n}\n","import { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { FRAMEWORK_ROOT, STYLES_DIR, resolveProjectFile, basePath, deployPath } from \"./paths\";\n\n/**\n * Build cache version — bump when the toolchain output contract changes\n * (e.g. Bun.build barrel optimization, Tailwind CLI upgrade). Old caches\n * with a mismatched version are discarded on read (see build.ts readCache).\n *\n * v6: pages became base-path aware (`meta.basePath`), and the resolved value\n * is folded into `basePathStamp()` below. Bumping here also invalidates any\n * cache written by an earlier config, so a base-path edit can never be\n * silently skipped as \"unchanged\".\n */\nexport const BUILD_CACHE_VERSION = 6;\n\n/**\n * Resolved docs URL prefix and deployment path, part of every cache key.\n *\n * The page cache is keyed by relative MDX path and the bundle/asset slots are\n * hashed from MDX source alone — neither changes when only `meta.basePath` or\n * `meta.baseURL`'s path changes. Without this stamp, editing either would leave\n * every key untouched and the build would skip every page, emitting HTML that\n * still points at the old prefix.\n */\nexport function basePathStamp(): string {\n return prefixStamp(basePath(), deployPath());\n}\n\n/**\n * Compose the cache stamp from both prefixes that shape generated URLs: the\n * docs prefix and the host's deployment path (from `meta.baseURL`). Either one\n * changing has to invalidate the cache, or a warm cache keeps serving HTML that\n * points at the old location.\n */\nexport function prefixStamp(resolvedBasePath: string, deploymentPath: string): string {\n if (deploymentPath.length === 0) return resolvedBasePath;\n return `${resolvedBasePath || \"/\"}@${deploymentPath}`;\n}\n\n/**\n * Toolchain fingerprint: Bun version on Bun, Deno version on Deno, Node elsewhere.\n */\nexport function runtimeStamp(): string {\n const g = globalThis as Record<string, unknown>;\n const bun = g.Bun as { version?: string } | undefined;\n if (typeof bun?.version === \"string\" && bun.version.length > 0) return `bun-${bun.version}`;\n const deno = g.Deno as { version?: { deno?: string } } | undefined;\n if (typeof deno?.version?.deno === \"string\" && deno.version.deno.length > 0)\n return `deno-${deno.version.deno}`;\n const proc = g.process as { version?: string } | undefined;\n if (typeof proc?.version === \"string\" && proc.version.length > 0) return `node-${proc.version}`;\n return \"node-unknown\";\n}\n\n/**\n * Framework source files that shape rendered HTML.\n *\n * Page cache entries are keyed by MDX source alone, so editing the renderer\n * (a template tweak, a new meta tag, base-path plumbing) would otherwise leave\n * every page a cache hit and keep serving HTML built by the old code. Hashing\n * these sources makes a framework edit invalidate the pages it affects.\n */\nconst RENDER_SOURCE_FILES = [\n \".docu/node/html.ts\",\n \".docu/node/html.shared.ts\",\n \".docu/node/seo.ts\",\n \".docu/node/utils.ts\",\n \".docu/node/paths.ts\",\n \".docu/node/base-path.ts\",\n \".docu/node/mdx.ts\",\n \".docu/node/search-indexer.ts\",\n \".docu/node/build.ts\",\n \".docu/node/build.impl.ts\",\n \".docu/node/server-routes.ts\",\n \".docu/components/DocsLayout.tsx\",\n \".docu/components/Navbar.tsx\",\n \".docu/pages/index.tsx\",\n \".docu/pages/404.tsx\",\n \".docu/pages/docs/[[...slug]].tsx\",\n] as const;\n\nlet renderStampCache: string | null = null;\n\n/**\n * Fingerprint of the framework's rendering sources.\n *\n * Memoized per process — the files cannot change mid-build, and hashing them\n * on every page would dominate build time. A missing file contributes nothing\n * so a partial install still yields a stable (if weaker) stamp.\n */\nexport function renderToolchainStamp(): string {\n if (renderStampCache !== null) return renderStampCache;\n const h = createHash(\"sha256\");\n h.update(`v${BUILD_CACHE_VERSION}`);\n for (const rel of RENDER_SOURCE_FILES) {\n const file = join(FRAMEWORK_ROOT, rel);\n try {\n if (!existsSync(file)) continue;\n h.update(rel).update(\"\\0\").update(readFileSync(file, \"utf-8\"));\n } catch {\n // unreadable source — skip it rather than break the build\n }\n }\n renderStampCache = h.digest(\"hex\").slice(0, 16);\n return renderStampCache;\n}\n\n/**\n * True when a CSS file can change Tailwind v4 output.\n * v4 is CSS-first: `@theme`, `@source`, `@plugin`, `@custom-variant`,\n * `@utility`, `@config`, `@apply`/`@variant`, and `@import \"tailwindcss\"`\n * all live in CSS. Plain CSS without these cannot affect the CLI output,\n * so it is excluded to avoid false cache busts. Broad match deliberate:\n * false positive busts safe, false negative serves stale CSS.\n */\nexport function isTailwindRelevantCss(content: string): boolean {\n return (\n content.includes(\"@theme\") ||\n content.includes(\"@source\") ||\n content.includes(\"@plugin\") ||\n content.includes(\"@custom-variant\") ||\n content.includes(\"@utility\") ||\n content.includes(\"@config\") ||\n content.includes(\"@apply\") ||\n content.includes(\"@variant\") ||\n content.includes(\"@layer\") ||\n content.includes(\"tailwindcss\")\n );\n}\n\nconst IMPORT_RE = /@import\\s+(?:url\\()?[\"']([^\"']+)[\"']/g;\nconst MAX_IMPORT_DEPTH = 10;\n\n/** Resolve `./` + `../` imports only — bare specifiers are version-pinned deps. */\nfunction resolveRelativeImport(spec: string, fromDir: string): string | undefined {\n if (!spec.startsWith(\".\")) return undefined;\n const clean = spec.split(\"?\")[0]!.split(\"#\")[0]!;\n if (clean.length === 0) return undefined;\n return join(fromDir, clean);\n}\n\n/**\n * Read a CSS file plus transitively imported relative files.\n * Non-relevant files contribute \"\" themselves, but their imports are still\n * followed (nested file may carry `@theme`). `visited` breaks import cycles.\n * Missing/unreadable files resolve to \"\" — never throws.\n */\nfunction readCssWithImports(path: string, visited: Set<string>, depth = 0): string {\n if (depth > MAX_IMPORT_DEPTH || visited.has(path)) return \"\";\n visited.add(path);\n let content = \"\";\n try {\n if (!existsSync(path)) return \"\";\n content = readFileSync(path, \"utf-8\");\n } catch {\n return \"\";\n }\n let out = isTailwindRelevantCss(content) ? content : \"\";\n try {\n const dir = join(path, \"..\");\n for (const m of content.matchAll(IMPORT_RE)) {\n const resolved = resolveRelativeImport(m[1] ?? \"\", dir);\n if (resolved) out += readCssWithImports(resolved, visited, depth + 1);\n }\n } catch {\n // import scan failed — keep what we have\n }\n return out;\n}\n\nfunction scanCssDir(dir: string, visited: Set<string>): string {\n let out = \"\";\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const e of entries) {\n const full = join(dir, e.name);\n if (e.isDirectory()) {\n if (e.name === \"assets\" || e.name.startsWith(\".\") || e.name === \"node_modules\") continue;\n out += scanCssDir(full, visited);\n } else if (e.name.endsWith(\".css\")) {\n out += readCssWithImports(full, visited);\n }\n }\n } catch {\n // docs/ missing — nothing to add\n }\n return out;\n}\n\nfunction scanRootCss(root: string, visited: Set<string>): string {\n let out = \"\";\n try {\n const entries = readdirSync(root, { withFileTypes: true });\n for (const e of entries) {\n if (e.isFile() && e.name.endsWith(\".css\")) {\n out += readCssWithImports(join(root, e.name), visited);\n }\n }\n } catch {\n // unreadable root — proceed without\n }\n return out;\n}\n\n/** Hash @theme/@source/@plugin-bearing CSS in project docs/ + root *.css. */\nfunction tailwindCssThemeInputs(root: string): string {\n const visited = new Set<string>();\n return scanCssDir(join(root, \"docs\"), visited) + scanRootCss(root, visited);\n}\n\nconst TAILWIND_CONFIG_FILES = [\n \"tailwind.config.ts\",\n \"tailwind.config.js\",\n \"tailwind.config.mjs\",\n \"tailwind.config.cjs\",\n \"tailwind.config.mts\",\n \"tailwind.config.cts\",\n \"postcss.config.js\",\n \"postcss.config.mjs\",\n \"postcss.config.cjs\",\n];\n\n/**\n * JS config still affects v4 when referenced via `@config`\n * (plus PostCSS pipeline config). Content hashed when present.\n */\nfunction tailwindJsConfigInputs(root: string): string {\n let out = \"\";\n for (const name of TAILWIND_CONFIG_FILES) {\n try {\n const p = join(root, name);\n if (existsSync(p)) out += readFileSync(p, \"utf-8\") + \"\\0\";\n } catch {\n // unreadable config — skip\n }\n }\n return out;\n}\n\nfunction readInstalledVersion(pkg: string, roots: string[]): string {\n for (const root of roots) {\n try {\n const p = join(root, \"node_modules\", ...pkg.split(\"/\"), \"package.json\");\n if (existsSync(p)) {\n const parsed = JSON.parse(readFileSync(p, \"utf-8\")) as { version?: string };\n if (typeof parsed.version === \"string\" && parsed.version.length > 0) return parsed.version;\n }\n } catch {\n // try next root\n }\n }\n return \"\";\n}\n\n/** Pin resolved CSS-affecting deps into the key (installed version wins). */\nfunction tailwindVersionPins(root: string): string {\n const names = [\"tailwindcss\", \"@tailwindcss/cli\", \"@tailwindcss/typography\", \"daisyui\"] as const;\n let extra = \"\";\n const roots = [root, FRAMEWORK_ROOT];\n for (const name of names) {\n const installed = readInstalledVersion(name, roots);\n if (installed) extra += `${name}@${installed}\\0`;\n }\n try {\n const pkgPath = join(root, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n for (const name of names) {\n const range = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name] ?? \"\";\n if (range) extra += `${name}:${range}\\0`;\n }\n }\n } catch {\n // package.json unreadable — proceed without version pin\n }\n return extra;\n}\n\n/**\n * Extra Tailwind inputs beyond globals.css + theme.\n * v4 is CSS-first: user overrides live in `@theme`/`@source`/`@plugin`\n * blocks inside CSS files under the project root (e.g. docs slash star dot css),\n * plus JS config referenced via `@config` and installed plugin versions.\n * Missing files resolve to \"\" — never throws.\n */\nexport function tailwindExtraInputs(root: string = resolveProjectFile()): string {\n return (\n tailwindCssThemeInputs(root) + \"\\0\" + tailwindJsConfigInputs(root) + tailwindVersionPins(root)\n );\n}\n\n/**\n * Shared Tailwind cache key: globals.css + theme + tailwind config +\n * toolchain version. Used by both hydrate.ts (Bun) and hydrate.node.ts\n * (Vite) so the two runtimes agree on filenames. Segments joined with NUL\n * so `(\"ab\",\"c\")` and `(\"a\",\"bc\")` hash differently.\n */\nexport function computeTailwindCacheKey(\n globals: string,\n themeSuffix: string,\n projectRoot: string = resolveProjectFile()\n): string {\n const h = createHash(\"sha256\");\n h.update(globals);\n h.update(\"\\0\");\n h.update(themeSuffix);\n h.update(\"\\0\");\n h.update(tailwindExtraInputs(projectRoot));\n h.update(\"\\0\");\n h.update(runtimeStamp());\n h.update(\"\\0\");\n h.update(basePathStamp());\n h.update(\"\\0\");\n h.update(`v${BUILD_CACHE_VERSION}`);\n return h.digest(\"hex\").slice(0, 16);\n}\n\n/** Read a Tailwind entry plus relative imports for cache invalidation. */\nexport function readStyleCss(file = \"globals.css\"): string {\n return readCssWithImports(join(STYLES_DIR, file), new Set());\n}\n\n/** Backward-compatible alias for the docs stylesheet entry. */\nexport function readGlobalsCss(): string {\n return readStyleCss();\n}\n\n/**\n * Atomic file write: tmp + rename so a crash mid-write never leaves a\n * half-written cache/CSS behind. Tmp name includes pid so parallel\n * builds (`bun run --parallel`) do not clobber each other.\n */\nexport async function atomicWriteFile(\n writeFile: (p: string, data: string | Uint8Array) => Promise<void>,\n rename: (from: string, to: string) => Promise<void>,\n unlink: (p: string) => Promise<void>,\n target: string,\n data: string | Uint8Array\n): Promise<void> {\n const g = globalThis as Record<string, unknown>;\n const proc = g.process as { pid?: number } | undefined;\n const pid = typeof proc?.pid === \"number\" ? proc.pid : Math.floor(Math.random() * 1e9);\n const tmp = `${target}.tmp-${pid}-${Date.now()}`;\n try {\n await writeFile(tmp, data);\n await rename(tmp, target);\n } catch (err) {\n try {\n await unlink(tmp);\n } catch {\n // best-effort tmp cleanup\n }\n throw err;\n }\n}\n\n/** Wire memory-pressure hook once: OS low-memory → drop parsed page maps. */\nlet memoryPressureHooked = false;\nexport function hookMemoryPressure(clear: () => void): void {\n if (memoryPressureHooked) return;\n memoryPressureHooked = true;\n try {\n const g = globalThis as Record<string, unknown>;\n const proc = g.process as\n | {\n on?: (event: string, listener: (level: string) => void) => void;\n }\n | undefined;\n proc?.on?.(\"memoryPressure\", () => {\n try {\n clear();\n } catch {\n // never throw out of a pressure handler\n }\n });\n } catch {\n // runtimes without the event (Node < Bun 1.4 backport) — no-op\n }\n}\n\n/**\n * Hash of compiled MDX module sources (sorted keys + content).\n * Used to skip the JS bundle rebuild when no page content changed.\n */\nexport function hashMdxSources(mdxSources: Record<string, string>): string {\n const h = createHash(\"sha256\");\n const slugs = Object.keys(mdxSources).sort();\n h.update(\n `v${BUILD_CACHE_VERSION}:${runtimeStamp()}:${basePathStamp()}:${renderToolchainStamp()}:`\n );\n for (const slug of slugs) {\n h.update(slug);\n h.update(\"\\0\");\n h.update(mdxSources[slug]);\n h.update(\"\\0\");\n }\n return h.digest(\"hex\").slice(0, 16);\n}\n","/**\n * File System-Based Route Scanner\n *\n * Auto-scan docs folder at build-time, merge with manual docu.json routes.\n * User can override with manual routes in docu.json.\n *\n * Docs folder structure:\n * docs/\n * ├── getting-started/\n * │ ├── introduction.mdx → /getting-started/introduction\n * │ └── installation.mdx → /getting-started/installation\n * └── api/\n * └── reference.mdx → /api/reference\n */\n\nimport type { DocuRoute } from \"./types\";\nimport { readdirSync, statSync } from \"node:fs\";\nimport { join, relative, extname, sep } from \"node:path\";\n\ninterface FileNode {\n name: string;\n relPath: string;\n absPath: string;\n isDirectory: boolean;\n children?: FileNode[];\n}\n\nfunction toTitleCase(str: string): string {\n return str\n .replace(/-/g, \" \")\n .replace(/_/g, \" \")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nfunction isDocFile(filename: string): boolean {\n const ext = extname(filename).toLowerCase();\n return [\".mdx\", \".md\"].includes(ext);\n}\n\nfunction normalizePath(path: string): string {\n return path.split(sep).join(\"/\");\n}\n\n/**\n * Recursively scan a directory and return file tree\n *\n * @param dirPath - Absolute path to scan\n * @param docsRoot - Root docs folder for relative path calculation\n */\nfunction scanDir(dirPath: string, docsRoot: string): FileNode[] {\n const nodes: FileNode[] = [];\n\n let entries: string[];\n try {\n entries = readdirSync(dirPath).sort();\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") throw err;\n return nodes;\n }\n\n for (const entry of entries) {\n if (entry.startsWith(\".\") || entry === \"assets\") continue;\n\n const absPath = join(dirPath, entry);\n\n try {\n const stat = statSync(absPath);\n\n if (stat.isDirectory()) {\n const children = scanDir(absPath, docsRoot);\n if (children.length > 0) {\n nodes.push({\n name: entry,\n relPath: normalizePath(relative(docsRoot, absPath)),\n absPath,\n isDirectory: true,\n children,\n });\n }\n } else if (stat.isFile() && isDocFile(entry)) {\n nodes.push({\n name: entry,\n relPath: normalizePath(relative(docsRoot, absPath).replace(/\\.(mdx|md)$/, \"\")),\n absPath,\n isDirectory: false,\n });\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") throw err;\n continue;\n }\n }\n\n return nodes;\n}\n\nfunction fileNodesToRoutes(nodes: FileNode[], parentHref = \"\"): DocuRoute[] {\n const routes: DocuRoute[] = [];\n\n for (const node of nodes) {\n if (!node.isDirectory) {\n const baseName = node.name.replace(/\\.(mdx|md)$/, \"\");\n const isIndexFile = /^(index|readme)$/i.test(baseName);\n if (isIndexFile) continue;\n\n const segment = node.relPath.split(\"/\").pop()!;\n const href = `/${segment}`;\n\n routes.push({\n title: toTitleCase(baseName),\n href,\n });\n } else {\n const dirTitle = toTitleCase(node.name);\n const segment = node.relPath.split(\"/\").pop()!;\n const dirHref = `/${segment}`;\n\n const children = fileNodesToRoutes(node.children || [], dirHref);\n\n if (children.length === 0) continue;\n\n const hasIndexFile = (node.children || []).some(\n (c) => !c.isDirectory && /^(index|readme)\\.(mdx|md)$/i.test(c.name)\n );\n\n if (hasIndexFile) {\n routes.push({\n title: dirTitle,\n href: dirHref,\n ...(parentHref === \"\" && {\n context: { title: dirTitle, icon: \"CircleHelp\", description: dirTitle },\n }),\n items: children,\n });\n } else {\n routes.push({\n title: dirTitle,\n href: dirHref,\n noLink: true,\n ...(parentHref === \"\" && {\n context: { title: dirTitle, icon: \"CircleHelp\", description: dirTitle },\n }),\n items: children,\n });\n }\n }\n }\n\n return routes;\n}\n\n/**\n * Scan docs folder and convert to DocuRoute[]\n *\n * @param docsPath - Path to docs folder (default: \"./docs\")\n */\nexport function scanDocsFolder(docsPath = \"./docs\"): DocuRoute[] {\n const absDocsPath = join(process.cwd(), docsPath);\n const nodes = scanDir(absDocsPath, absDocsPath);\n return fileNodesToRoutes(nodes);\n}\n\n/**\n * Resolve routes:\n * 1. If docu.json has routes, use them (manual priority)\n * 2. Else, scan docs folder (auto-detect)\n *\n * @param docuJsonRoutes - Routes from docu.json (optional)\n */\nexport function resolveRoutes(docuJsonRoutes?: DocuRoute[]): DocuRoute[] {\n if (docuJsonRoutes && docuJsonRoutes.length > 0) {\n return docuJsonRoutes;\n }\n return scanDocsFolder();\n}\n","import { createHash } from \"node:crypto\";\nimport { basename, join } from \"node:path\";\nimport { mkdir, rename, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { resolveTheme, generateThemeCss, presetRegistry } from \"@docubook/themes-colors\";\nimport {\n ASSETS_DIR,\n cleanOldBundles,\n LIB_DIR,\n STYLES_DIR,\n loadDocuConfig,\n resolveBasePath,\n servedDeployPath,\n} from \"./paths\";\nimport { atomicWriteFile, computeTailwindCacheKey, readStyleCss } from \"./cache-key\";\nimport { resolveRoutes } from \"./fs-scanner\";\nimport type { AssetManifest, DocuRoute } from \"./types\";\nimport type { ThemeConfig } from \"@docubook/themes-colors\";\n\nconst themeRegistry = presetRegistry;\n\nexport function createMdxModuleEntries(mdxSources: Record<string, string>) {\n return Object.keys(mdxSources)\n .sort()\n .map((slug) => ({\n slug,\n id: `docubook-mdx-page-${createHash(\"sha256\").update(slug).digest(\"hex\").slice(0, 16)}`,\n }));\n}\n\n/**\n * Read the effective theme config with this priority:\n * 1. FLAME_THEME env var (CLI --theme flag)\n * 2. docu.json theme.colors field\n */\nexport function getThemeConfig(): ThemeConfig | undefined {\n if (process.env.FLAME_THEME) {\n return process.env.FLAME_THEME;\n }\n const config = loadDocuConfig();\n return config.themes?.colors;\n}\n\n/** Append theme CSS to compiled Tailwind output based on theme config. */\nexport function buildThemeCss(baseCss: string, themeConfig: unknown): string {\n try {\n const resolved = resolveTheme(themeConfig as ThemeConfig | undefined | null, themeRegistry);\n return baseCss + \"\\n\" + generateThemeCss(resolved);\n } catch (err) {\n console.warn(\n `[flame] Failed to resolve theme CSS: ${err instanceof Error ? err.message : String(err)}`\n );\n return baseCss;\n }\n}\n\n/** Compute inline theme CSS for FOUC prevention. */\nexport function computeInlineThemeCss(): string | undefined {\n try {\n const themeColors = getThemeConfig();\n if (themeColors) {\n const resolved = resolveTheme(themeColors, themeRegistry);\n return generateThemeCss(resolved);\n }\n } catch (err) {\n console.warn(\n `[flame] Failed to compute inline theme CSS: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n return undefined;\n}\n\nfunction themeCacheSuffix(): string {\n try {\n const themeColors = getThemeConfig();\n return themeColors ? JSON.stringify(themeColors) : \"\";\n } catch {\n return \"\";\n }\n}\n\nfunction tailwindCacheKey(styleFile: string): string {\n return computeTailwindCacheKey(readStyleCss(styleFile), `${styleFile}\\0${themeCacheSuffix()}`);\n}\n\n/** Run Tailwind CLI, caching each route stylesheet by content hash. */\nasync function buildTailwindCss(\n name: string,\n styleFile: string\n): Promise<{ file: string; content: string }> {\n const key = tailwindCacheKey(styleFile);\n const cachedFile = `${name}-${key}.css`;\n const cachedPath = join(ASSETS_DIR, cachedFile);\n\n if (existsSync(cachedPath)) {\n return { file: cachedFile, content: await Bun.file(cachedPath).text() };\n }\n\n const tmpCss = join(ASSETS_DIR, `_tmp-${name}-${key}.css`);\n const proc = Bun.spawn(\n [\"bun\", \"x\", \"@tailwindcss/cli\", \"-i\", join(STYLES_DIR, styleFile), \"-o\", tmpCss, \"--minify\"],\n { stdout: \"ignore\", stderr: \"pipe\" }\n );\n await proc.exited;\n if (proc.exitCode !== 0) {\n const err = await new Response(proc.stderr).text();\n throw new Error(`Tailwind CSS build failed:\\n${err}`);\n }\n\n let cssContent = await Bun.file(tmpCss).text();\n await unlink(tmpCss).catch(() => {});\n\n try {\n const themeColors = getThemeConfig();\n if (themeColors) cssContent = buildThemeCss(cssContent, themeColors);\n } catch (err) {\n console.warn(\n `[flame] Failed to resolve theme config: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n if (!existsSync(cachedPath)) {\n const { writeFile } = await import(\"node:fs/promises\");\n await atomicWriteFile(writeFile, rename, unlink, cachedPath, cssContent);\n }\n\n return { file: cachedFile, content: cssContent };\n}\n\nexport async function buildClientBundle(\n /** slug → compiled MDX ESM module source (program format) for static hydration. */\n mdxSources: Record<string, string> = {}\n): Promise<AssetManifest> {\n await mkdir(ASSETS_DIR, { recursive: true });\n await cleanOldBundles();\n\n const nodeEnv = process.env.NODE_ENV || \"development\";\n const mdxEntries = createMdxModuleEntries(mdxSources);\n const mdxEntriesById = new Map(mdxEntries.map((entry) => [entry.id, entry]));\n const result = await Bun.build({\n entrypoints: [join(LIB_DIR, \"client.ts\"), join(LIB_DIR, \"home-client.ts\")],\n outdir: ASSETS_DIR,\n splitting: true,\n naming: {\n entry: \"[name]-[hash].[ext]\",\n chunk: \"chunks/[name]-[hash].[ext]\",\n asset: \"assets/[name]-[hash].[ext]\",\n },\n target: \"browser\",\n minify: nodeEnv === \"production\",\n define: { \"process.env.NODE_ENV\": JSON.stringify(nodeEnv) },\n plugins: [\n {\n name: \"docu-config\",\n setup(build) {\n build.onResolve({ filter: /client-routes$/ }, (args) => ({\n path: args.path,\n namespace: \"client-routes\",\n }));\n build.onLoad({ filter: /.*/, namespace: \"client-routes\" }, () => {\n const config = loadDocuConfig();\n const resolved = {\n ...config,\n routes: resolveRoutes(config.routes as DocuRoute[] | undefined),\n };\n return {\n contents: [\n `import type { DocuRoute, DocuConfig } from \"./types\";`,\n `const docuConfig = ${JSON.stringify(resolved)};`,\n `export const routes = docuConfig.routes || [];`,\n `export const config = docuConfig;`,\n // The client bundle cannot read docu.json at runtime, so the\n // resolved prefix is inlined here — same value the server-side\n // render and the static build use.\n `export const basePath = ${JSON.stringify(resolveBasePath(config))};`,\n // Dev serves the project from the origin root, so the host's\n // deployment path only reaches the production bundle.\n `export const deployPath = ${JSON.stringify(servedDeployPath())};`,\n ].join(\"\\n\"),\n loader: \"ts\",\n };\n });\n },\n },\n {\n name: \"mdx-hydrate\",\n setup(build) {\n build.onResolve({ filter: /^docubook-mdx-page-[a-f0-9]{16}$/ }, (args) => ({\n path: args.path,\n namespace: \"mdx-module\",\n }));\n build.onLoad({ filter: /.*/, namespace: \"mdx-module\" }, (args) => {\n const entry = mdxEntriesById.get(args.path);\n const contents = entry == null ? undefined : mdxSources[entry.slug];\n if (contents == null) {\n return {\n errors: [{ text: `unknown mdx module: ${args.path}` }],\n contents: \"\",\n loader: \"js\",\n };\n }\n return { contents, loader: \"js\" };\n });\n build.onResolve({ filter: /mdx-manifest$/ }, (args) => ({\n path: args.path,\n namespace: \"mdx-manifest\",\n }));\n build.onLoad({ filter: /.*/, namespace: \"mdx-manifest\" }, () => {\n const map = mdxEntries\n .map(({ slug, id }) => `${JSON.stringify(slug)}: () => import(${JSON.stringify(id)})`)\n .join(\", \");\n return {\n contents: `export const mdxModules = { ${map} };\\n`,\n loader: \"js\",\n };\n });\n },\n },\n ],\n });\n\n if (!result.success) {\n for (const log of result.logs) console.error(log);\n throw new Error(\"Client bundle failed\");\n }\n\n const entryFiles = result.outputs\n .filter((output) => output.kind === \"entry-point\")\n .map((output) => basename(output.path));\n const docsJs = entryFiles.find((file) => file.startsWith(\"client-\"));\n const homeJs = entryFiles.find((file) => file.startsWith(\"home-client-\"));\n if (!docsJs || !homeJs) {\n throw new Error(\"Client bundle produced incomplete entry-point outputs\");\n }\n\n const [{ file: docsCss }, { file: siteCss }] = await Promise.all([\n buildTailwindCss(\"docs\", \"globals.css\"),\n buildTailwindCss(\"site\", \"site.css\"),\n ]);\n\n const manifest: AssetManifest = {\n docs: { js: docsJs, css: docsCss },\n home: { js: homeJs, css: siteCss },\n notFound: { css: siteCss },\n };\n await Bun.write(join(ASSETS_DIR, \"manifest.json\"), JSON.stringify(manifest));\n return manifest;\n}\n","/** Client bundle builder for Node/Deno runtimes. */\n\nimport { execFile } from \"node:child_process\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { promisify } from \"node:util\";\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { build as viteBuild } from \"vite\";\nimport {\n ASSETS_DIR,\n FRAMEWORK_ROOT,\n cleanOldBundles,\n LIB_DIR,\n STYLES_DIR,\n loadDocuConfig,\n resolveBasePath,\n servedDeployPath,\n} from \"./paths\";\nimport { buildThemeCss, createMdxModuleEntries, getThemeConfig } from \"./hydrate\";\nimport { atomicWriteFile, computeTailwindCacheKey, readStyleCss } from \"./cache-key\";\nimport { resolveRoutes } from \"./fs-scanner\";\nimport { normalizeImporterPath } from \"./security\";\nimport type { AssetManifest, DocuConfig, DocuRoute } from \"./types\";\n\n/** Extract Lucide icon names from user docu.json configuration. */\nfunction extractConfigIcons(config: DocuConfig): string[] {\n const icons: string[] = [];\n const pushIf = (value: string | undefined) => {\n if (value) icons.push(value);\n };\n config.home?.hero?.actions?.forEach((action) => pushIf(action.icon));\n config.home?.features?.forEach((feature) => pushIf(feature.icon));\n (function walk(routes: DocuRoute[]) {\n for (const route of routes) {\n pushIf(route.context?.icon);\n if (route.items) walk(route.items);\n }\n })(config.routes ?? []);\n return [...new Set(icons.filter((name) => /^[A-Z]/.test(name)))];\n}\n\nexport { buildThemeCss, computeInlineThemeCss, getThemeConfig } from \"./hydrate\";\n\nexport function viteChunkFileName(chunk: { name: string }): string {\n const name = chunk.name.replace(/^_docubook-mdx-page-/, \"docubook-mdx-page-\");\n return `chunks/${name}-[hash].js`;\n}\n\nconst execFileAsync = promisify(execFile);\n\nfunction resolveTailwindBin(): string {\n const require = createRequire(import.meta.url);\n const pkgPath = require.resolve(\"@tailwindcss/cli/package.json\");\n const pkg = require(pkgPath) as { bin: string | Record<string, string> };\n const binRel = typeof pkg.bin === \"string\" ? pkg.bin : pkg.bin.tailwindcss;\n return join(dirname(pkgPath), binRel);\n}\n\nfunction themeCacheSuffix(): string {\n try {\n const themeColors = getThemeConfig();\n return themeColors ? JSON.stringify(themeColors) : \"\";\n } catch {\n return \"\";\n }\n}\n\nfunction tailwindCacheKey(styleFile: string): string {\n return computeTailwindCacheKey(readStyleCss(styleFile), `${styleFile}\\0${themeCacheSuffix()}`);\n}\n\nasync function buildTailwindCss(\n name: string,\n styleFile: string\n): Promise<{ file: string; content: string }> {\n const key = tailwindCacheKey(styleFile);\n const cachedFile = `${name}-${key}.css`;\n const cachedPath = join(ASSETS_DIR, cachedFile);\n\n if (existsSync(cachedPath)) {\n return { file: cachedFile, content: readFileSync(cachedPath, \"utf-8\") };\n }\n\n const tmpCss = join(ASSETS_DIR, `_tmp-${name}-${key}.css`);\n const bin = resolveTailwindBin();\n const tailwindArgs = [\"-i\", join(STYLES_DIR, styleFile), \"-o\", tmpCss, \"--minify\"];\n const isDeno = \"Deno\" in globalThis;\n const args = isDeno ? [\"run\", \"-A\", bin, ...tailwindArgs] : [bin, ...tailwindArgs];\n try {\n await execFileAsync(process.execPath, args, { maxBuffer: 16 * 1024 * 1024 });\n } catch (err) {\n const stderr = (err as { stderr?: string }).stderr ?? String(err);\n throw new Error(`Tailwind CSS build failed:\\n${stderr}`, { cause: err });\n }\n\n let cssContent = await readFile(tmpCss, \"utf-8\");\n await unlink(tmpCss).catch(() => {});\n\n try {\n const themeColors = getThemeConfig();\n if (themeColors) cssContent = buildThemeCss(cssContent, themeColors);\n } catch (err) {\n console.warn(\n `[flame] Failed to resolve theme config: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n if (!existsSync(cachedPath)) {\n await atomicWriteFile(writeFile, rename, unlink, cachedPath, cssContent);\n }\n\n return { file: cachedFile, content: cssContent };\n}\n\nconst NODE_BUILTINS_RE = new RegExp(\n `^(node:.*|${builtinModules.map((module) => module.replace(/\\//g, \"\\\\/\")).join(\"|\")})$`\n);\n\nlet lucideRealEntry: string | undefined;\n\nfunction getLucideRealEntry(): string {\n if (!lucideRealEntry) {\n lucideRealEntry = createRequire(import.meta.url).resolve(\"lucide-react\");\n }\n return lucideRealEntry;\n}\n\nconst LUCIDE_IMPORT_RE = /import\\s*\\{([^}]+)\\}\\s*from\\s*[\"']lucide-react[\"']/g;\nconst LUCIDE_ICON_RE = /^[A-Z]/;\n\nfunction scanDirLucideIcons(dir: string, set: Set<string>): void {\n if (!existsSync(dir)) return;\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name !== \"node_modules\") scanDirLucideIcons(full, set);\n } else if (/\\.(js|ts|tsx)$/.test(entry.name)) {\n const content = readFileSync(full, \"utf-8\");\n for (const match of content.matchAll(LUCIDE_IMPORT_RE)) {\n for (const specifier of match[1].split(\",\")) {\n const name = specifier\n .trim()\n .split(/\\s+as\\s+/)[0]\n .trim();\n if (LUCIDE_ICON_RE.test(name)) set.add(name);\n }\n }\n }\n }\n } catch (err) {\n console.warn(\n `[flame] Failed to scan lucide icons: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\nfunction collectAllLucideIcons(): string[] {\n const icons = new Set<string>();\n scanDirLucideIcons(join(FRAMEWORK_ROOT, \".docu/components\"), icons);\n scanDirLucideIcons(join(FRAMEWORK_ROOT, \".docu/pages\"), icons);\n const dependencyDirs = [\n join(FRAMEWORK_ROOT, \"..\", \"mdx-content\", \"dist\"),\n join(FRAMEWORK_ROOT, \"..\", \"ui-react\", \"dist\"),\n join(FRAMEWORK_ROOT, \"..\", \"core\", \"dist\"),\n join(FRAMEWORK_ROOT, \"..\", \"themes-colors\", \"dist\"),\n ];\n for (const dir of dependencyDirs) scanDirLucideIcons(resolve(dir), icons);\n return [...icons];\n}\n\nexport async function buildClientBundle(\n /** slug → compiled MDX ESM module source (program format) for static hydration. */\n mdxSources: Record<string, string> = {}\n): Promise<AssetManifest> {\n await mkdir(ASSETS_DIR, { recursive: true });\n await cleanOldBundles();\n const nodeEnv = process.env.NODE_ENV || \"development\";\n const mdxEntries = createMdxModuleEntries(mdxSources);\n const mdxEntriesById = new Map(mdxEntries.map((entry) => [entry.id, entry]));\n const docsEntryPath = join(LIB_DIR, \"client.ts\");\n const homeEntryPath = join(LIB_DIR, \"home-client.ts\");\n\n const bundle = await viteBuild({\n configFile: false,\n publicDir: false,\n define: { \"process.env.NODE_ENV\": JSON.stringify(nodeEnv) },\n plugins: [\n {\n name: \"node-builtin-stub\",\n resolveId(id) {\n if (NODE_BUILTINS_RE.test(id)) return `\\0node-stub:${id}`;\n return null;\n },\n load(id) {\n if (!id.startsWith(\"\\0node-stub:\")) return null;\n return \"export default {}; export {};\";\n },\n },\n {\n name: \"lucide-optimize\",\n resolveId(id, importer) {\n if (id !== \"lucide-react\") return null;\n if (importer) {\n const normalized = normalizeImporterPath(importer);\n if (normalized.includes(\"/markdown/dist/\")) return null;\n }\n return \"\\0lucide-virt\";\n },\n load(id) {\n if (id !== \"\\0lucide-virt\") return null;\n const scanned = collectAllLucideIcons();\n const configured = extractConfigIcons(loadDocuConfig());\n const allIcons = [...new Set([...scanned, ...configured])];\n return `export { ${allIcons.join(\", \")} } from ${JSON.stringify(getLucideRealEntry())};`;\n },\n },\n {\n name: \"docu-config\",\n resolveId(id) {\n if (!/client-routes$/.test(id)) return null;\n return \"\\0client-routes\";\n },\n load(id) {\n if (id !== \"\\0client-routes\") return null;\n const config = loadDocuConfig();\n const resolved = {\n ...config,\n routes: resolveRoutes(config.routes as DocuRoute[] | undefined),\n };\n return [\n `const docuConfig = ${JSON.stringify(resolved)};`,\n `export const routes = docuConfig.routes || [];`,\n `export const config = docuConfig;`,\n `export const basePath = ${JSON.stringify(resolveBasePath(config))};`,\n // Dev serves the project from the origin root, so the host's\n // deployment path only reaches the production bundle.\n `export const deployPath = ${JSON.stringify(servedDeployPath())};`,\n ].join(\"\\n\");\n },\n },\n {\n name: \"mdx-hydrate\",\n resolveId(id) {\n if (/mdx-manifest$/.test(id)) return \"\\0mdx-manifest\";\n if (/^docubook-mdx-page-[a-f0-9]{16}$/.test(id)) return `\\0${id}`;\n return null;\n },\n load(id) {\n if (id === \"\\0mdx-manifest\") {\n const map = mdxEntries\n .map(({ slug, id }) => `${JSON.stringify(slug)}: () => import(${JSON.stringify(id)})`)\n .join(\", \");\n return `export const mdxModules = { ${map} };\\n`;\n }\n if (!id.startsWith(\"\\0docubook-mdx-page-\")) return null;\n const entry = mdxEntriesById.get(id.slice(1));\n const contents = entry == null ? undefined : mdxSources[entry.slug];\n if (contents == null) throw new Error(`unknown mdx module: ${id}`);\n return contents;\n },\n },\n ],\n build: {\n outDir: ASSETS_DIR,\n emptyOutDir: false,\n sourcemap: true,\n minify: nodeEnv === \"production\",\n target: \"es2020\",\n rollupOptions: {\n input: { client: docsEntryPath, \"home-client\": homeEntryPath },\n output: {\n format: \"es\",\n entryFileNames: \"[name]-[hash].js\",\n chunkFileNames: viteChunkFileName,\n assetFileNames: \"assets/[name]-[hash][extname]\",\n },\n },\n },\n });\n\n const outputs = Array.isArray(bundle) ? bundle : [bundle];\n let docsJs: string | undefined;\n let homeJs: string | undefined;\n for (const item of outputs) {\n if (!(\"output\" in item)) continue;\n for (const output of item.output) {\n if (output.type !== \"chunk\" || !output.isEntry) continue;\n if (output.name === \"client\") docsJs = output.fileName;\n if (output.name === \"home-client\") homeJs = output.fileName;\n }\n }\n if (!docsJs || !homeJs) {\n throw new Error(\"Client bundle produced incomplete entry-point outputs\");\n }\n\n const [{ file: docsCss }, { file: siteCss }] = await Promise.all([\n buildTailwindCss(\"docs\", \"globals.css\"),\n buildTailwindCss(\"site\", \"site.css\"),\n ]);\n\n const manifest: AssetManifest = {\n docs: { js: docsJs, css: docsCss },\n home: { js: homeJs, css: siteCss },\n notFound: { css: siteCss },\n };\n await writeFile(join(ASSETS_DIR, \"manifest.json\"), JSON.stringify(manifest));\n return manifest;\n}\n","/**\n * Runtime-neutral git helpers — same behavior as the git functions in\n * `utils.ts` (Bun-only, protected) but spawning via `node:child_process`,\n * which works on Bun, Node.js, and Deno. `mdx.ts` imports from here.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { stat } from \"node:fs/promises\";\n\nfunction runGit(args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\"git\", args, { maxBuffer: 16 * 1024 * 1024 }, (err, stdout) => {\n if (err) reject(err);\n else resolve(stdout);\n });\n });\n}\n\nfunction sanitizePath(filePath: string): string | null {\n const cleanPath = filePath.replace(/^\\//, \"\");\n if (!cleanPath || !/^[a-zA-Z0-9\\-_/.\\s]+$/.test(cleanPath) || /(^|\\/)\\.\\.($|\\/)/.test(cleanPath))\n return null;\n return cleanPath;\n}\n\n/** Get git last modified date for a file */\nexport async function getGitLastModified(filePath: string): Promise<string | null> {\n const cleanPath = sanitizePath(filePath);\n if (!cleanPath) return null;\n try {\n const text = await runGit([\"log\", \"-1\", \"--format=%cI\", \"--\", cleanPath]);\n const date = text.trim();\n return date || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Fallback to filesystem mtime when git is unavailable (shallow clone, no .git, etc.).\n * Returns ISO 8601 date string or null.\n */\nexport async function getFilesystemMtime(filePath: string): Promise<string | null> {\n try {\n const stats = await stat(filePath);\n return stats.mtime.toISOString();\n } catch {\n return null;\n }\n}\n\n/** Batch git last modified dates for multiple files in a single spawn */\nexport async function getGitLastModifiedBatch(filePaths: string[]): Promise<Map<string, string>> {\n const result = new Map<string, string>();\n if (filePaths.length === 0) return result;\n\n const safePaths: string[] = [];\n for (const fp of filePaths) {\n const cleanPath = sanitizePath(fp);\n if (!cleanPath) {\n console.warn(`[git] getGitLastModifiedBatch: skipping invalid path \"${fp}\"`);\n continue;\n }\n safePaths.push(cleanPath);\n }\n\n if (safePaths.length === 0) return result;\n\n try {\n const text = await runGit([\n \"log\",\n \"--format=%cI\",\n \"--name-only\",\n \"--diff-filter=ACMR\",\n ...safePaths,\n ]);\n let currentDate = \"\";\n\n for (const line of text.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(trimmed)) {\n currentDate = trimmed;\n } else if (currentDate && !result.has(trimmed)) {\n result.set(trimmed, currentDate);\n }\n }\n } catch (err) {\n console.error(\"Failed to get git last modified batch for\", filePaths, err);\n }\n\n return result;\n}\n","import React from \"react\";\nimport type { Pluggable } from \"unified\";\nimport { z, type ZodType } from \"zod\";\nimport {\n serialize,\n rehypeCollectTocs,\n type TocItem,\n extractFrontmatterWithContent,\n createDefaultRehypePlugins,\n createDefaultRemarkPlugins,\n MDXRemote,\n} from \"@docubook/core\";\nimport { createMdxComponents } from \"@docubook/markdown\";\nimport { getGitLastModified, getGitLastModifiedBatch, getFilesystemMtime } from \"./git\";\nimport { basePath, servedDeployPath } from \"./paths\";\nimport { isDocsPath, rebaseContentPath } from \"./base-path\";\n\n/**\n * Does an author-written absolute path belong to the docs site?\n *\n * At a root deployment the docs own `/`, so every in-site path is a candidate\n * (the historical rule for authored content); otherwise the shared\n * {@link isDocsPath} gate applies and sibling app routes stay untouched.\n */\nfunction isContentPath(pathname: string, resolvedBasePath: string): boolean {\n return resolvedBasePath.length === 0 || isDocsPath(pathname, resolvedBasePath);\n}\n\n/** Split an authored value into its pathname and any `?query`/`#fragment`. */\nfunction splitContentPath(value: string): { pathname: string; suffix: string } {\n const cut = value.search(/[?#]/);\n if (cut === -1) return { pathname: value.replace(/\\/+$/, \"\") || \"/\", suffix: \"\" };\n return {\n pathname: value.slice(0, cut).replace(/\\/+$/, \"\") || \"/\",\n suffix: value.slice(cut),\n };\n}\n\n/**\n * Resolve an author-written content **link** for the deployment.\n *\n * Authors link to sibling pages the way they sit on disk (`/docs/guide/y`). The\n * static build serves those pages as flat `.html` files, and a non-default\n * `meta.basePath` — or a host that publishes the dist under a path (a GitHub\n * Pages project site) — moves the authored segment. Re-base it onto the\n * configured prefix, add the deployment path, and keep the `.html` suffix on\n * page links. Returns null when nothing moves, so the default `/docs`\n * deployment keeps emitting the same HTML.\n */\nexport function resolveContentHref(\n value: unknown,\n resolvedBasePath: string = basePath(),\n deploymentPath: string = servedDeployPath()\n): string | null {\n if (typeof value !== \"string\") return null;\n if (/^[a-z][a-z\\d+.-]*:|^\\/\\//i.test(value)) return null; // external / protocol-relative\n if (!value.startsWith(\"/\") || value === \"/\") return null;\n\n const { pathname, suffix } = splitContentPath(value);\n if (!isContentPath(pathname, resolvedBasePath)) return null;\n\n const rebased = rebaseContentPath(pathname, resolvedBasePath);\n // The docs root is a directory index, fragments keep the authored\n // extensionless form (hosts with `try_files` serve the pair), and files keep\n // their own suffix.\n const isDirectory =\n rebased === \"/\" || rebased === resolvedBasePath || /\\.[a-z0-9]+$/i.test(rebased);\n const target = isDirectory || suffix.includes(\"#\") ? rebased : `${rebased}.html`;\n const resolved = `${deploymentPath}${target}${suffix}`;\n return resolved === value ? null : resolved;\n}\n\n/**\n * Resolve an author-written content **asset** path (``)\n * for the deployment. Same re-basing rules as {@link resolveContentHref}, minus\n * the `.html` suffix — assets are files, not routes.\n */\nexport function resolveContentSrc(\n value: unknown,\n resolvedBasePath: string = basePath(),\n deploymentPath: string = servedDeployPath()\n): string | null {\n if (typeof value !== \"string\") return null;\n if (/^[a-z][a-z\\d+.-]*:|^\\/\\//i.test(value)) return null;\n if (!value.startsWith(\"/\") || value === \"/\") return null;\n\n const { pathname, suffix } = splitContentPath(value);\n if (!isContentPath(pathname, resolvedBasePath)) return null;\n\n const resolved = `${deploymentPath}${rebaseContentPath(pathname, resolvedBasePath)}${suffix}`;\n return resolved === value ? null : resolved;\n}\n\n/** Element → attribute pairs whose author-written values are content assets. */\nconst CONTENT_ASSET_ATTRS: Record<string, string> = {\n img: \"src\",\n source: \"src\",\n video: \"src\",\n audio: \"src\",\n};\n\ninterface HastNode {\n type: string;\n tagName?: string;\n properties?: Record<string, unknown>;\n children?: HastNode[];\n}\n\ninterface MdastNode {\n type: string;\n // MDX JSX nodes carry their props as an attributes array\n attributes?: { type: string; name: string; value: unknown }[];\n children?: MdastNode[];\n}\n\n/**\n * Rehype plugin: point author-written hrefs at the deployed docs paths, and\n * author-written asset paths at the deployed asset tree.\n *\n * Links cover both shapes — plain markdown `[text](/docs/page)` and images and\n * media (`` → `<img src>`) — which only exist in the\n * HAST phase. Skips: external URLs, anchors, the root index, and anything the\n * resolver leaves unchanged.\n */\nfunction rehypeDocsHtmlLinks() {\n return (tree: HastNode) => {\n function walk(node: HastNode): void {\n if (node.type === \"element\" && node.properties) {\n if (node.tagName === \"a\") {\n const fixed = resolveContentHref(node.properties.href);\n if (fixed) node.properties.href = fixed;\n } else {\n const attr = node.tagName ? CONTENT_ASSET_ATTRS[node.tagName] : undefined;\n if (attr) {\n const fixed = resolveContentSrc(node.properties[attr]);\n if (fixed) node.properties[attr] = fixed;\n }\n }\n }\n if (node.children) {\n for (const child of node.children) walk(child);\n }\n }\n walk(tree);\n return tree;\n };\n}\n\n/**\n * Remark plugin: append `.html` to internal docs hrefs on MDX JSX nodes.\n *\n * MDX JSX elements (`<Card href=\"…\">`, `<LinkCard href=\"…\">`, etc.) live in\n * the MDAST as `mdxJsxFlowElement` / `mdxJsxTextElement` nodes. They are\n * compiled directly to JavaScript by the MDX compiler *before* rehype runs,\n * so a rehype plugin can never see them as `<a>` elements. This remark plugin\n * intercepts them at the MDAST phase where their `attributes` array is still\n * accessible and mutable.\n *\n * Skips: same rules as `resolveContentHref` (external URLs, anchors, already\n * resolved paths).\n */\nfunction remarkMdxJsxDocsHtmlLinks() {\n return (tree: MdastNode) => {\n function walk(node: MdastNode): void {\n if (\n (node.type === \"mdxJsxFlowElement\" || node.type === \"mdxJsxTextElement\") &&\n node.attributes\n ) {\n for (const attr of node.attributes) {\n if (attr.type === \"mdxJsxAttribute\" && attr.name === \"href\") {\n const fixed = resolveContentHref(attr.value);\n if (fixed) attr.value = fixed;\n }\n }\n }\n if (node.children) {\n for (const child of node.children) walk(child);\n }\n }\n walk(tree);\n return tree;\n };\n}\n\nexport { getGitLastModifiedBatch };\n\nexport interface MdxResult {\n content: React.ReactElement;\n compiledSource: string;\n frontmatter: Frontmatter;\n tocs: TocItem[];\n}\n\n/**\n * DocuBook frontmatter contract — single source of truth for frontmatter\n * fields. Add new properties here; types and validation derive from it.\n * YAML coerces unquoted values, so string fields use `z.coerce.*`.\n * `.passthrough()` keeps unknown fields (e.g. `author: wildan`, `tags`)\n * in the parsed output — arbitrary frontmatter metadata stays available\n * via `frontmatterField(frontmatter, key)` instead of being silently\n * stripped by Zod's default object parsing.\n */\nexport const frontmatterSchema = z\n .object({\n title: z.coerce.string().optional(),\n description: z.coerce.string().optional(),\n image: z.coerce.string().optional(),\n date: z.coerce.string().optional(),\n })\n .passthrough();\n\nexport type Frontmatter = z.infer<typeof frontmatterSchema>;\n\n/**\n * Read a string field from frontmatter after the plugin transform chain\n * (which widens the type to `Record<string, unknown>`). Returns \"\" when\n * missing or not a string.\n */\nexport function frontmatterField(frontmatter: Record<string, unknown>, key: string): string {\n return typeof frontmatter[key] === \"string\" ? (frontmatter[key] as string) : \"\";\n}\n\n/**\n * Zod schema validating frontmatter after extraction.\n * Must satisfy the frontmatter contract (defaults to `frontmatterSchema`).\n */\nexport type FrontmatterSchema = ZodType<Frontmatter>;\n\n/**\n * Compile MDX/MD content into a React element and compiled source.\n *\n * @param rawMdx - Raw MDX/MD file content\n * @param filePath - Relative file path for git date lookup\n * @param gitDates - Optional pre-fetched git last-modified map\n * @param remarkPlugins - Additional remark plugins (merged after defaults, optional)\n * @param rehypePlugins - Additional rehype plugins (merged after defaults, optional)\n * @param frontmatterSchema - Custom schema overriding the default contract\n */\n/**\n * Shared compile core used by `compileMdx` (SSR) and `compileMdxModule`\n * (static hydration). Strips frontmatter, merges the doc plugin chain\n * (defaults + .html link fixes + user plugins) and runs `serialize()`.\n */\nasync function serializeWithDocPlugins(\n rawMdx: string,\n opts: {\n outputFormat?: \"function-body\" | \"program\";\n remarkPlugins?: Pluggable[];\n rehypePlugins?: Pluggable[];\n frontmatterSchema?: FrontmatterSchema;\n } = {},\n pre?: { frontmatter: Frontmatter; strippedContent: string }\n) {\n // Parse-once: when the prePass already extracted the frontmatter + stripped\n // content, reuse it instead of re-parsing (the SSR phase skips extraction).\n const { strippedContent, frontmatter } =\n pre ??\n (opts.frontmatterSchema\n ? extractFrontmatterWithContent<Frontmatter>(rawMdx, opts.frontmatterSchema)\n : extractFrontmatterWithContent<Frontmatter>(rawMdx));\n\n const defaultRemark = createDefaultRemarkPlugins();\n const defaultRehype = createDefaultRehypePlugins();\n\n // remarkMdxJsxDocsHtmlLinks must run before user plugins so custom remark\n // transforms see already-fixed hrefs. rehypeDocsHtmlLinks handles plain\n // markdown [text](path) → <a> elements in the HAST phase.\n const finalRemark = [...defaultRemark, remarkMdxJsxDocsHtmlLinks, ...(opts.remarkPlugins ?? [])];\n const tocs: TocItem[] = [];\n const finalRehype: Pluggable[] = [\n ...defaultRehype,\n rehypeDocsHtmlLinks,\n ...(opts.rehypePlugins ?? []),\n [rehypeCollectTocs, tocs],\n ];\n\n // v2 contract: plain markdown + directives only — authored JSX tags are\n // not parsed (dropped, content kept as text). Return the frontmatter parsed\n // above — `serialize()` only parses it when `parseFrontmatter` is set.\n return serialize(strippedContent, {\n outputFormat: opts.outputFormat,\n format: \"md\",\n mdxOptions: {\n rehypePlugins: finalRehype,\n remarkPlugins: finalRemark,\n },\n }).then((serialized) => ({ ...serialized, frontmatter, strippedContent, tocs }));\n}\n\n/**\n * Compile MDX/MD content into a React element and compiled source.\n *\n * @param rawMdx - Raw MDX/MD file content\n * @param filePath - Relative file path for git date lookup\n * @param gitDates - Optional pre-fetched git last-modified map\n * @param remarkPlugins - Additional remark plugins (merged after defaults, optional)\n * @param rehypePlugins - Additional rehype plugins (merged after defaults, optional)\n * @param frontmatterSchema - Custom schema overriding the default contract\n */\nexport async function compileMdx(\n rawMdx: string,\n filePath: string,\n gitDates?: Map<string, string>,\n remarkPlugins?: Pluggable[],\n rehypePlugins?: Pluggable[],\n frontmatterSchema?: FrontmatterSchema,\n /** Pre-pass extracted data — avoids re-parsing frontmatter in the SSR phase. */\n pre?: { frontmatter: Frontmatter; strippedContent: string }\n): Promise<MdxResult> {\n const frontmatter =\n pre?.frontmatter ??\n (frontmatterSchema\n ? extractFrontmatterWithContent<Frontmatter>(rawMdx, frontmatterSchema).frontmatter\n : extractFrontmatterWithContent<Frontmatter>(rawMdx).frontmatter);\n const serialized = await serializeWithDocPlugins(\n rawMdx,\n { remarkPlugins, rehypePlugins, frontmatterSchema },\n pre\n );\n\n const components = createMdxComponents();\n const content = React.createElement(MDXRemote, {\n compiledSource: serialized.compiledSource,\n scope: {},\n frontmatter: {},\n components,\n });\n\n const date =\n frontmatter.date ||\n gitDates?.get(filePath) ||\n (await getGitLastModified(filePath)) ||\n (await getFilesystemMtime(filePath)) ||\n undefined;\n\n return {\n content,\n compiledSource: serialized.compiledSource,\n frontmatter: { ...frontmatter, date },\n tocs: serialized.tocs,\n };\n}\n\n/**\n * Compile MDX to a real ESM module source (program format) for static\n * client-side hydration — the browser imports and executes it via the bundler\n * instead of `new Function(compiledSource)`. Uses the same plugin chain as\n * `compileMdx` so the hydrated tree matches the SSR output.\n */\n/**\n * Frontmatter records collected once during compilation — pagination title /\n * description and other metadata consumers read from here instead of\n * re-reading + re-parsing files (parse-once contract: the frontmatter is\n * already parsed by `serializeWithDocPlugins`).\n */\nconst pageFrontmatter = new Map<string, Frontmatter>();\n\n/** Register a page's frontmatter, keyed by its href. */\nexport function registerPageFrontmatter(href: string, frontmatter: Frontmatter): void {\n pageFrontmatter.set(href, frontmatter);\n}\n\n/** Look up a page's frontmatter (undefined when not yet compiled). */\nexport function getPageFrontmatter(href: string): Frontmatter | undefined {\n return pageFrontmatter.get(href);\n}\n\n/**\n * Frontmatter-stripped content from the prePass — lets the SSR compile\n * phase skip its own `extractFrontmatterWithContent` (parse-once across\n * both compile phases).\n */\nconst pageStripped = new Map<string, string>();\n\nexport function registerPageStripped(href: string, stripped: string): void {\n pageStripped.set(href, stripped);\n}\n\nexport function getPageStripped(href: string): string | undefined {\n return pageStripped.get(href);\n}\n\n/**\n * Original (pre-transform) file content, cached during the prePass so the\n * page loop does not re-read the file from disk — one read per file.\n */\nconst pageContent = new Map<string, string>();\n\nexport function registerPageContent(href: string, raw: string): void {\n pageContent.set(href, raw);\n}\n\nexport function getPageContent(href: string): string | undefined {\n return pageContent.get(href);\n}\n\n/** Drop derived page maps under OS memory pressure (Bun 1.4 `memoryPressure`). */\nexport function clearDerivedPageCaches(): void {\n pageContent.clear();\n pageStripped.clear();\n pageFrontmatter.clear();\n}\n\nexport async function compileMdxModule(\n rawMdx: string,\n remarkPlugins?: Pluggable[],\n rehypePlugins?: Pluggable[],\n /** Page href — registers the frontmatter (title/description/image/date)\n * once for pagination and metadata consumers. */\n href?: string\n): Promise<string> {\n const serialized = await serializeWithDocPlugins(rawMdx, {\n outputFormat: \"program\",\n remarkPlugins,\n rehypePlugins,\n });\n if (href) {\n registerPageFrontmatter(href, serialized.frontmatter as Frontmatter);\n registerPageStripped(href, serialized.strippedContent);\n }\n return serialized.compiledSource;\n}\n","export { cn, parseDate, formatDate, formatDate2 } from \"@docubook/core\";\nexport {\n withBasePath,\n assetHref,\n applyBasePath,\n rebaseContentPath,\n stripDocsHtmlSuffix,\n matchDocsSlug,\n} from \"./base-path\";\n\nimport { DEFAULT_BASE_PATH, isDocsPath, rebaseContentPath } from \"./base-path\";\n\n/**\n * Client-safe utilities shared by SSR and the browser bundle.\n *\n * This module MUST NOT import Node built-ins (`node:fs`, `node:path`, ...):\n * Bun's bundler injects a `node:path` polyfill into browser builds for any\n * bundled module that imports it. Filesystem/git helpers live in\n * `./server-utils` (server-only).\n */\n\nexport function isExternalUrl(url: string): boolean {\n return /^(https?:\\/\\/|\\/\\/)/.test(url);\n}\n\n/** Suffix an internal docs link with `.html` to match the flat static build output. */\nexport function docsHtmlHref(path: string): string {\n return `${path}.html`;\n}\n\n/**\n * Resolve an authored nav/menu link for the current deployment.\n *\n * Docs pages ship as flat `.html` files, so `/docs/guide/routing` has to request\n * `/docs/guide/routing.html`, while the docs root itself stays a directory index\n * and keeps no suffix. Authored `/docs/...` paths are re-based onto the\n * configured prefix, so one `docu.json` keeps working at a custom subpath\n * (`/repo`) or at a root deployment (`\"\"`). External URLs, hash targets and\n * paths that already name a file pass through untouched.\n */\nexport function docsNavHref(link: string, resolvedBasePath: string = DEFAULT_BASE_PATH): string {\n if (isExternalUrl(link) || !link.startsWith(\"/\")) return link;\n\n const cut = link.search(/[?#]/);\n const suffix = cut === -1 ? \"\" : link.slice(cut);\n const pathname = (cut === -1 ? link : link.slice(0, cut)).replace(/\\/+$/, \"\") || \"/\";\n\n // Sibling routes on the same origin are not docs pages — leave them verbatim.\n if (!isDocsPath(pathname, resolvedBasePath)) return link;\n\n const rebased = rebaseContentPath(pathname, resolvedBasePath);\n\n // The docs root is a directory index, and anything with an extension is\n // already a file — neither takes the `.html` suffix.\n if (rebased === \"/\" || rebased === resolvedBasePath || /\\.[a-z0-9]+$/i.test(rebased)) {\n return `${rebased}${suffix}`;\n }\n return `${rebased}.html${suffix}`;\n}\n\n/**\n * Does `pathname` refer to a link returned by {@link docsNavHref}?\n *\n * Nav links reach the browser in two forms: the generated `.html` URL and the\n * extensionless route a visitor may have typed (the dev server maps both), so\n * active states have to accept the pair.\n */\nexport function docsNavActive(pathname: string, href: string): boolean {\n const extensionless = href.endsWith(\".html\") ? href.slice(0, -\".html\".length) : href;\n return (\n pathname === href || pathname === extensionless || pathname.startsWith(`${extensionless}/`)\n );\n}\n\nexport function getPath(url: string): string {\n try {\n return new URL(url).pathname;\n } catch (err) {\n console.error(\"Failed to parse URL\", url, err);\n return url;\n }\n}\n","/**\n * Search Index Generator\n *\n * Scans MDX files at build-time and produces a search-index.json\n * with hierarchy-based records (similar to Algolia DocSearch crawler).\n *\n * Hierarchy levels:\n * lvl0 = section (parent route title)\n * lvl1 = page title (frontmatter title or h1)\n * lvl2-lvl6 = headings h2-h6\n * content = first paragraph/list items after each heading\n */\n\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join } from \"node:path\";\nimport { getPageContent } from \"./mdx\";\nimport { extractFrontmatterWithContent } from \"@docubook/core\";\nimport { frontmatterField } from \"./mdx\";\nimport { DOCS_DIR, ASSETS_DIR, loadDocuConfig, basePath, deployPath } from \"./paths\";\nimport { scanMdxFiles } from \"./server-utils\";\nimport { docsHtmlHref } from \"./utils\";\n\nconst docuConfig = loadDocuConfig();\n\nexport interface SearchRecord {\n url: string;\n hierarchy: {\n lvl0: string;\n lvl1: string | null;\n lvl2: string | null;\n lvl3: string | null;\n lvl4: string | null;\n lvl5: string | null;\n lvl6: string | null;\n };\n content: string | null;\n type: \"lvl0\" | \"lvl1\" | \"lvl2\" | \"lvl3\" | \"lvl4\" | \"lvl5\" | \"lvl6\" | \"content\";\n}\n\ninterface Frontmatter {\n title?: string;\n description?: string;\n [key: string]: unknown;\n}\n\nfunction getSectionTitle(filePath: string): string {\n const parts = filePath.split(\"/\");\n if (parts.length > 1) {\n const section = docuConfig.routes?.find(\n (r) => r.href === `/${parts[0]}` || r.href === parts[0]\n );\n if (section) return section.title;\n }\n return docuConfig.meta?.title || \"Docs\";\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nexport function stripJsx(content: string): string {\n let result = content;\n let prev = \"\";\n while (result !== prev) {\n prev = result;\n result = result\n .replace(/<[A-Z][\\w.]*[\\s\\S]*?\\/>/g, \"\")\n .replace(/<[A-Z][\\w.]*[\\s\\S]*?>([\\s\\S]*?)<\\/[A-Z][\\w.]*>/g, \"$1\");\n }\n return result;\n}\n\n/**\n * Absolute URL for a search record.\n *\n * Records are clicked straight from the search modal, so they must carry both\n * prefixes: the docs prefix inside the dist and the host's deployment path\n * (e.g. `/repo` on a GitHub Pages project site), which no relative depth can\n * express.\n */\nexport function searchRecordUrl(\n filePath: string,\n resolvedBasePath: string = basePath(),\n deploymentPath: string = deployPath()\n): string {\n return docsHtmlHref(`${deploymentPath}${resolvedBasePath}/${filePath}`);\n}\n\nexport function extractRecords(filePath: string, raw: string): SearchRecord[] {\n const { frontmatter, strippedContent: content } = extractFrontmatterWithContent<Frontmatter>(raw);\n const records: SearchRecord[] = [];\n const url = searchRecordUrl(filePath);\n const lvl0 = getSectionTitle(filePath);\n const lvl1 = frontmatterField(frontmatter, \"title\") || null;\n\n const hierarchy = {\n lvl0,\n lvl1,\n lvl2: null as string | null,\n lvl3: null as string | null,\n lvl4: null as string | null,\n lvl5: null as string | null,\n lvl6: null as string | null,\n };\n\n if (lvl1) {\n records.push({\n url,\n hierarchy: { ...hierarchy },\n content: frontmatterField(frontmatter, \"description\") || null,\n type: \"lvl1\",\n });\n }\n\n const plainContent = stripJsx(content);\n const lines = plainContent.split(\"\\n\");\n let currentParagraph: string[] = [];\n let inCodeBlock = false;\n\n const flushParagraph = () => {\n if (currentParagraph.length > 0) {\n const text = currentParagraph.join(\" \").trim();\n if (text) {\n records.push({\n url: buildAnchorUrl(),\n hierarchy: { ...hierarchy },\n content: text,\n type: \"content\",\n });\n }\n currentParagraph = [];\n }\n };\n\n const buildAnchorUrl = () => {\n for (let i = 6; i >= 2; i--) {\n const key = `lvl${i}` as keyof typeof hierarchy;\n if (hierarchy[key]) return `${url}#${slugify(hierarchy[key]!)}`;\n }\n return url;\n };\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith(\"```\")) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n if (/^import\\s+[\\w{*]/.test(trimmed) || /^export\\s+[\\w{*]/.test(trimmed)) continue;\n\n const headingMatch = trimmed.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n flushParagraph();\n const level = headingMatch[1].length;\n const title = headingMatch[2].replace(/[*`[\\]]/g, \"\").trim();\n\n if (level === 1) {\n // Frontmatter title is authoritative; use H1 only as a fallback.\n for (let i = 2; i <= 6; i++) {\n (hierarchy as Record<string, string | null>)[`lvl${i}`] = null;\n }\n if (!hierarchy.lvl1) hierarchy.lvl1 = title;\n continue;\n }\n\n for (let i = level; i <= 6; i++) {\n (hierarchy as Record<string, string | null>)[`lvl${i}`] = null;\n }\n hierarchy[`lvl${level}` as keyof typeof hierarchy] = title;\n\n if (level >= 2) {\n records.push({\n url: `${url}#${slugify(title)}`,\n hierarchy: { ...hierarchy },\n content: null,\n type: `lvl${level}` as SearchRecord[\"type\"],\n });\n }\n continue;\n }\n\n if (trimmed === \"\" || trimmed === \"---\") {\n flushParagraph();\n continue;\n }\n\n if (/^\\|.+\\|/.test(trimmed)) continue;\n\n const cleaned = trimmed\n .replace(/^[-*+]\\s+/, \"\") // list markers\n .replace(/^\\d+\\.\\s+/, \"\") // ordered list\n .replace(/^>\\s+/, \"\") // blockquote\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\")\n .replace(/\\*([^*]+)\\*/g, \"$1\")\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\")\n .trim();\n\n if (cleaned) currentParagraph.push(cleaned);\n }\n\n flushParagraph();\n return records;\n}\n\nexport async function generateSearchIndex(docsDir?: string, outputDir?: string): Promise<number> {\n const docs = resolve(docsDir || DOCS_DIR);\n const dist = resolve(outputDir || ASSETS_DIR);\n await mkdir(dist, { recursive: true });\n\n const mdxFiles = await scanMdxFiles(docs);\n const results = await Promise.all(\n mdxFiles.map(async (file) => {\n // Parse-once: reuse the prePass-cached raw content when available —\n // no second disk read of every file.\n const raw = getPageContent(`/${file.path}`) ?? (await readFile(file.absPath, \"utf-8\"));\n return extractRecords(file.path, raw);\n })\n );\n const allRecords = results.flat();\n\n await writeFile(join(dist, \"search-index.json\"), JSON.stringify(allRecords));\n return allRecords.length;\n}\n","/**\n * Optional Sentry error tracking integration.\n * Active only when SENTRY_DSN environment variable is set.\n * Requires @sentry/bun as an optional peer dependency.\n */\n\nlet sentry: typeof import(\"@sentry/bun\") | null = null;\nlet initialized = false;\n\nexport async function initSentry(): Promise<void> {\n const dsn = process.env.SENTRY_DSN;\n if (!dsn) return;\n\n try {\n sentry = await import(\"@sentry/bun\");\n sentry.init({\n dsn,\n environment: process.env.NODE_ENV || \"development\",\n release: process.env.SENTRY_RELEASE || undefined,\n });\n initialized = true;\n } catch {\n // @sentry/bun not installed — silently skip\n sentry = null;\n initialized = false;\n }\n}\n\nexport function captureException(err: unknown, context?: Record<string, unknown>): void {\n if (!initialized || !sentry) return;\n sentry.captureException(err, context ? { extra: context } : undefined);\n}\n\nexport function isEnabled(): boolean {\n return initialized;\n}\n","import {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n} from \"@docubook/ui-react/breadcrumbs\";\n\nexport interface DocsBreadcrumbProps {\n paths: string[];\n}\n\nfunction toTitleCase(input: string): string {\n return input\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\nexport default function DocsBreadcrumb({ paths }: DocsBreadcrumbProps) {\n return (\n <Breadcrumb className=\"py-4\">\n <BreadcrumbList>\n <BreadcrumbItem>\n <span className=\"text-muted-foreground\">Docs</span>\n </BreadcrumbItem>\n {paths.map((path, index) => (\n <BreadcrumbItem key={`${path}-${index}`}>\n {index < paths.length - 1 ? (\n <span className=\"text-muted-foreground\">{toTitleCase(path)}</span>\n ) : (\n <BreadcrumbPage className=\"text-base-content\">{toTitleCase(path)}</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n ))}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n","import { loadDocuConfig } from \"./paths\";\nimport type { DocuRoute } from \"./types\";\nimport { resolveRoutes } from \"./fs-scanner\";\nimport { DOCS_DIR } from \"./paths\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { extractFrontmatter } from \"@docubook/core\";\nimport { getPageFrontmatter, registerPageFrontmatter } from \"./mdx\";\nimport type { Frontmatter } from \"./mdx\";\n\nconst docuConfig = loadDocuConfig();\nexport const routes: DocuRoute[] = resolveRoutes(docuConfig.routes);\n\nexport function flattenRoutes(): string[] {\n const paths: string[] = [];\n\n function traverse(route: DocuRoute, section = \"\") {\n const fullPath = route.href.startsWith(section)\n ? route.href\n : `${section}${route.href}`.replace(/\\/+/g, \"/\");\n if (route.href && !route.noLink) {\n paths.push(fullPath);\n }\n if (route.items) {\n route.items.forEach((item) => traverse(item, fullPath));\n }\n }\n\n routes.forEach((route) => traverse(route));\n return paths;\n}\n\nexport function getRouteMap(): Map<string, string> {\n const map = new Map<string, string>();\n\n function traverse(route: DocuRoute, section = \"\") {\n const fullPath = route.href.startsWith(section)\n ? route.href\n : `${section}${route.href}`.replace(/\\/+/g, \"/\");\n map.set(fullPath, route.title);\n if (route.items) {\n route.items.forEach((item) => traverse(item, fullPath));\n }\n }\n\n routes.forEach((route) => traverse(route));\n return map;\n}\n\n/**\n * Single pagination entry builder (DRY) — one `readPageFrontmatter` call\n * serves both prev + next from the parse-once registry, so no file is\n * re-read or re-parsed. `description` rides along on prev too; the UI\n * keeps the paired prev minimal by design and only renders the rich\n * title + description when prev stands alone (last page, no next).\n */\nfunction toPaginationEntry(href: string, routeMap: Map<string, string>) {\n const fm = readPageFrontmatter(href);\n return {\n href,\n title: fm.title || routeMap.get(href) || \"\",\n description: fm.description || \"\",\n };\n}\n\n/**\n * Frontmatter for a page — read from the parse-once registry (populated\n * during compilation) instead of re-reading + re-parsing the file. Falls\n * back to a direct read only for pages the dev server has not compiled yet,\n * and caches the result back into the registry.\n */\nfunction readPageFrontmatter(href: string): Frontmatter {\n const registered = getPageFrontmatter(href);\n if (registered) return registered;\n\n let fm: Frontmatter = {};\n const rel = href.replace(/^\\/|$/g, \"\");\n for (const ext of [\".mdx\", \".md\"]) {\n for (const file of [join(DOCS_DIR, `${rel}${ext}`), join(DOCS_DIR, `${rel}/index${ext}`)]) {\n try {\n fm = extractFrontmatter<Frontmatter>(readFileSync(file, \"utf-8\"));\n break;\n } catch {\n // not this file — try the next candidate\n }\n }\n if (Object.keys(fm).length) break;\n }\n registerPageFrontmatter(href, fm);\n return fm;\n}\n\nexport function getPreviousNext(pathname: string) {\n const normalizedPath = pathname.replace(/^\\/|$/g, \"\");\n\n // Docs index (/docs — DocsPage renders with pathname \"\" from slug []):\n // next-only navigation into the first docs page — never read the route\n // backward from the index, so prev stays null even if a page sits before\n // it in the route list.\n if (normalizedPath === \"docs\" || normalizedPath === \"\") {\n const paths = flattenRoutes();\n const routeMap = getRouteMap();\n const first = paths[0];\n if (!first) return { prev: null, next: null };\n return { prev: null, next: toPaginationEntry(first, routeMap) };\n }\n\n const paths = flattenRoutes();\n\n const index = paths.findIndex((href) => href === `/${normalizedPath}` || href === normalizedPath);\n\n if (index === -1) {\n return { prev: null, next: null };\n }\n\n const routeMap = getRouteMap();\n const prevHref = index > 0 ? paths[index - 1] : null;\n const nextHref = index < paths.length - 1 ? paths[index + 1] : null;\n\n return {\n prev: prevHref ? toPaginationEntry(prevHref, routeMap) : null,\n next: nextHref ? toPaginationEntry(nextHref, routeMap) : null,\n };\n}\n\nexport function getPagination(currentPath: string) {\n return getPreviousNext(currentPath);\n}\n\nexport function getSection(pathname: string): string {\n const parts = pathname.split(\"/\").filter(Boolean);\n return parts[0] || \"home\";\n}\n","import type { DocuRoute, DocuConfig } from \"./types\";\nimport { loadDocuConfig, resolveBasePath, resolveDeployPath } from \"./paths\";\nimport { resolveRoutes } from \"./fs-scanner\";\n\nconst docuConfig = loadDocuConfig();\nexport const routes: DocuRoute[] = resolveRoutes(docuConfig.routes || []);\nexport const config = docuConfig as unknown as DocuConfig;\n\n/**\n * URL prefix the site is served under (`\"\"` at the domain root, else `/prefix`).\n * Components use this instead of assuming `/docs`, so a subpath deployment does\n * not request assets from the domain root.\n */\nexport const basePath: string = resolveBasePath(docuConfig);\n\n/**\n * Path the host serves the dist root under (`\"\"` at an origin root, `/repo` for\n * a GitHub Pages project site — see `resolveDeployPath`). Root-absolute browser\n * requests (the search index) build their URL from it, because the client\n * bundle cannot read `docu.json` at runtime.\n */\nexport const deployPath: string = resolveDeployPath(docuConfig);\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { getPreviousNext } from \"../node/route\";\nimport { docsHtmlHref } from \"../node/utils\";\nimport { basePath } from \"../node/client-routes\";\nimport { PaginationDocs } from \"@docubook/ui-react/pagination\";\n\ninterface PaginationProps {\n pathname: string;\n className?: string;\n prevIcon?: ReactNode;\n nextIcon?: ReactNode;\n linkClassName?: string;\n}\n\nexport default function Pagination({\n pathname,\n className,\n prevIcon,\n nextIcon,\n linkClassName,\n}: PaginationProps) {\n const { prev, next } = getPreviousNext(pathname);\n\n if (!prev && !next) {\n return null;\n }\n\n return (\n <PaginationDocs\n // `description` rides along always; PaginationDocs keeps the paired prev\n // minimal by design and renders title + description only when prev is\n // alone (last page, no next) — single branch point, no duplicated logic.\n prev={\n prev\n ? {\n href: docsHtmlHref(`${basePath}${prev.href}`),\n title: prev.title,\n description: prev.description,\n }\n : undefined\n }\n next={\n next\n ? {\n href: docsHtmlHref(`${basePath}${next.href}`),\n title: next.title,\n description: next.description,\n }\n : undefined\n }\n className={className}\n prevIcon={prevIcon}\n nextIcon={nextIcon}\n linkClassName={linkClassName}\n />\n );\n}\n","import { PropsWithChildren } from \"react\";\n\nexport function Typography({ children }: PropsWithChildren) {\n return (\n <div className=\"prose prose-zinc dark:prose-invert prose-code:font-code dark:prose-code:bg-stone-900/25 prose-code:bg-stone-50 prose-pre:bg-background max-lg:prose-headings:scroll-mt-16 prose-headings:scroll-mt-4 prose-code:text-sm prose-code:leading-6 dark:prose-code:text-white prose-code:text-stone-800 prose-code:p-1 prose-code:rounded-md prose-code:border prose-img:rounded-md prose-img:border prose-code:before:content-none prose-code:after:content-none prose-code:px-1.5 prose-code:overflow-x-auto prose-img:my-3 prose-h2:my-4 prose-h2:mt-8 w-full max-w-full! pt-2\">\n {children}\n </div>\n );\n}\n","import { loadDocuConfig } from \"./paths\";\nimport type { SocialLink } from \"./types\";\n\nconst docuConfig = loadDocuConfig();\n\nexport function getEditLink(url: string, filePath: string): string {\n const configPath = docuConfig?.repo?.path || detectPlatformPath(url);\n const encodedPath = filePath.replace(/^\\//, \"\").split(\"/\").map(encodeURIComponent).join(\"/\");\n return `${url}/${configPath}`.replace(\"{filePath}\", encodedPath);\n}\n\n/**\n * Detect the default edit path template from the repo URL hostname.\n * Supports GitHub, GitLab, Bitbucket, Gitea (cloud + self-hosted),\n * Gogs, Forgejo, and Codeberg.\n * Falls back to Gitea-style for unknown hosts — override via repo.path.\n */\nexport function detectPlatformPath(url: string): string {\n try {\n const host = new URL(url).hostname;\n if (host === \"github.com\") return \"blob/main/{filePath}\";\n if (host === \"gitlab.com\") return \"-/blob/main/{filePath}\";\n if (host === \"bitbucket.org\") return \"src/main/{filePath}\";\n if (host === \"gitea.com\") return \"src/branch/main/{filePath}\";\n if (host === \"codeberg.org\") return \"src/branch/main/{filePath}\";\n // Gogs, Forgejo, or any self-hosted Gitea-compatible forge\n return \"src/branch/main/{filePath}\";\n } catch {\n return \"blob/main/{filePath}\";\n }\n}\n\nexport function isEditEnabled(): boolean {\n return docuConfig?.repo?.edit ?? false;\n}\n\nexport function getRepoUrl(): string {\n return docuConfig?.repo?.url || \"\";\n}\n\nexport function getSocialLinks(): SocialLink[] {\n return docuConfig?.footer?.social || [];\n}\n","import { SquarePen } from \"lucide-react\";\nimport { isEditEnabled, getEditLink, getRepoUrl } from \"../node/helpers\";\n\nexport interface EditWithProps {\n filePath: string;\n text?: string;\n className?: string;\n}\n\nexport default function EditWith({\n filePath,\n text = \"Edit this page\",\n className = \"\",\n}: EditWithProps) {\n if (!isEditEnabled()) return null;\n\n const repoUrl = getRepoUrl();\n if (!repoUrl) return null;\n\n const editUrl = getEditLink(repoUrl, filePath);\n\n return (\n <div className={`text-right text-sm ${className}`}>\n <a\n href={editUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Edit this page\"\n className=\"flex items-center gap-1 no-underline\"\n >\n <SquarePen className=\"h-4 w-4\" />\n {text}\n </a>\n </div>\n );\n}\n","import { getSocialLinks } from \"../node/helpers\";\n\nexport interface SocialProps {\n className?: string;\n size?: number;\n}\n\nfunction createIcon(pathData: string) {\n return function Icon({ className = \"\", size = 20 }: { className?: string; size?: number }) {\n return (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <path d={pathData} />\n </svg>\n );\n };\n}\n\nconst GithubIcon = createIcon(\n \"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\n);\nconst BitbucketIcon = createIcon(\n \"M.778 1.213a.768.768 0 00-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 00.77-.646l3.27-20.03a.768.768 0 00-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z\"\n);\nconst GitlabIcon = createIcon(\n \"m23.6004 9.5927-.0337-.0862L20.3.9814a.851.851 0 0 0-.3362-.405.8748.8748 0 0 0-.9997.0539.8748.8748 0 0 0-.29.4399l-2.2055 6.748H7.5375l-2.2057-6.748a.8573.8573 0 0 0-.29-.4412.8748.8748 0 0 0-.9997-.0537.8585.8585 0 0 0-.3362.4049L.4332 9.5015l-.0325.0862a6.0657 6.0657 0 0 0 2.0119 7.0105l.0113.0087.03.0213 4.976 3.7264 2.462 1.8633 1.4995 1.1321a1.0085 1.0085 0 0 0 1.2197 0l1.4995-1.1321 2.4619-1.8633 5.006-3.7489.0125-.01a6.0682 6.0682 0 0 0 2.0094-7.003z\"\n);\nconst NpmIcon = createIcon(\n \"M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z\"\n);\nconst YoutubeIcon = createIcon(\n \"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\"\n);\nconst TwitterIcon = createIcon(\n \"M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z\"\n);\nconst InstagramIcon = createIcon(\n \"M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077\"\n);\nconst LinkedinIcon = createIcon(\n \"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.528zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.226.792 24 1.771 24h20.451C23.2 24 24 23.226 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\"\n);\nconst FacebookIcon = createIcon(\n \"M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z\"\n);\nconst TelegramIcon = createIcon(\n \"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\"\n);\nconst DiscordIcon = createIcon(\n \"M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z\"\n);\nconst ThreadsIcon = createIcon(\n \"M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z\"\n);\nconst MastodonIcon = createIcon(\n \"M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z\"\n);\n\nconst iconMap: Record<string, ReturnType<typeof createIcon>> = {\n github: GithubIcon,\n gitlab: GitlabIcon,\n bitbucket: BitbucketIcon,\n npm: NpmIcon,\n youtube: YoutubeIcon,\n twitter: TwitterIcon,\n x: TwitterIcon,\n instagram: InstagramIcon,\n linkedin: LinkedinIcon,\n facebook: FacebookIcon,\n telegram: TelegramIcon,\n discord: DiscordIcon,\n threads: ThreadsIcon,\n mastodon: MastodonIcon,\n};\n\nexport function getSocialIcon(name: string) {\n const key = name.toLowerCase().replace(/\\s+/g, \"\");\n return iconMap[key] || null;\n}\n\nexport default function Social({ className = \"\", size = 16 }: SocialProps) {\n const socialLinks = getSocialLinks();\n\n if (!socialLinks?.length) return null;\n\n return (\n <div className={`flex gap-1 ${className}`}>\n {socialLinks.map((link) => {\n const Icon = getSocialIcon(link.name);\n return (\n <a\n key={link.name}\n href={link.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={link.name}\n className=\"btn-xs btn-circle btn-ghost text-muted-foreground\"\n >\n {Icon && <Icon size={size} />}\n </a>\n );\n })}\n </div>\n );\n}\n","import Social from \"./Social\";\n\nexport function Footer() {\n return (\n <footer className=\"text-muted-foreground mt-auto flex w-full flex-col items-start gap-4 py-6 sm:flex-row sm:items-center sm:justify-between\">\n <Social />\n <aside className=\"sm:ml-auto\">\n <p className=\"text-xs\">\n Made with{\" \"}\n <a\n href=\"https://docubook.pro\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"link link-hover text-muted-foreground font-medium\"\n >\n DocuBook\n </a>\n </p>\n </aside>\n </footer>\n );\n}\n","\"use client\";\n\nimport { ArrowUpIcon } from \"lucide-react\";\nimport { useEffect, useState, useCallback } from \"react\";\nimport { cn } from \"../node/utils\";\n\ninterface ScrollToProps {\n className?: string;\n showIcon?: boolean;\n offset?: number;\n onScrollToTop?: () => void;\n}\n\nexport function ScrollTo({ className, showIcon = true, onScrollToTop }: ScrollToProps) {\n const [isVisible, setIsVisible] = useState(false);\n\n const checkScroll = useCallback(() => {\n const container = document.getElementById(\"scroll-container\");\n const scrollY = container ? container.scrollTop : window.scrollY;\n const scrollHeight = container ? container.scrollHeight : document.documentElement.scrollHeight;\n const threshold = scrollHeight * 0.3;\n\n const shouldShow = scrollY > threshold;\n if (shouldShow !== isVisible) {\n setIsVisible(shouldShow);\n }\n }, [isVisible]);\n\n useEffect(() => {\n let timeoutId: ReturnType<typeof setTimeout>;\n const handleScroll = () => {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(checkScroll, 100);\n };\n\n const container = document.getElementById(\"scroll-container\") || window;\n container.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => {\n container.removeEventListener(\"scroll\", handleScroll);\n if (timeoutId) clearTimeout(timeoutId);\n };\n }, [checkScroll]);\n\n const scrollToTop = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n onScrollToTop?.();\n history.replaceState(null, \"\", \"#top\");\n const container = document.getElementById(\"scroll-container\");\n if (container) {\n container.scrollTo({ top: 0, behavior: \"smooth\" });\n } else {\n window.scrollTo({ top: 0, behavior: \"smooth\" });\n }\n },\n [onScrollToTop]\n );\n\n return (\n <div\n className={cn(\n \"border-base-300 mt-4 border-t pt-4\",\n \"transition-opacity duration-300\",\n isVisible ? \"opacity-100\" : \"pointer-events-none opacity-0\",\n className\n )}\n >\n <a\n href=\"#top\"\n onClick={scrollToTop}\n className={cn(\n \"inline-flex items-center text-sm\",\n \"link link-hover text-base-content/60 hover:text-base-content\",\n \"transition-all duration-200 hover:translate-y-px\"\n )}\n aria-label=\"Scroll to top\"\n >\n {showIcon && <ArrowUpIcon className=\"mr-1 h-3.5 w-3.5 shrink-0\" />}\n <span>Scroll to Top</span>\n </a>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { ListIcon } from \"lucide-react\";\nimport { cn } from \"../node/utils\";\nimport { ScrollTo } from \"./ScrollTo\";\nimport { TocItem } from \"../node/types\";\n\ninterface TocProps {\n tocs: TocItem[];\n}\n\nexport default function Toc({ tocs }: TocProps) {\n const [activeId, setActiveId] = useState<string | null>(null);\n const clickedIdRef = useRef<string | null>(null);\n const clickTimerRef = useRef<ReturnType<typeof setTimeout>>(null);\n const activeIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n activeIdRef.current = activeId;\n }, [activeId]);\n\n // Single source of truth for the anchor offset — used by BOTH the scroll\n // observer and the TOC click scroll so they can never disagree. Reads the\n // CSS scroll-margin-top (prose-headings:scroll-mt-4 desktop /\n // scroll-mt-16 mobile) so a change in one place updates both, and the\n // heading lands exactly where the browser would put a native anchor jump.\n const getAnchorOffset = useCallback((): number => {\n if (typeof window === \"undefined\") return 100;\n const first = tocs[0] ? document.getElementById(tocs[0].href.slice(1)) : null;\n const margin = first ? parseFloat(getComputedStyle(first).scrollMarginTop) : 0;\n return margin || 100;\n }, [tocs]);\n\n useEffect(() => {\n // Desktop-only TOC — on mobile this island is display:none but still\n // mounted; letting its observer run would hijack the URL hash while the\n // mobile bar owns TOC behavior there.\n if (typeof window === \"undefined\" || window.innerWidth < 1024) return;\n if (!tocs.length) return;\n\n const isDesktop = window.innerWidth >= 1024;\n const container = isDesktop ? document.getElementById(\"scroll-container\") : null;\n const scrollTarget = container || window;\n const offset = getAnchorOffset();\n\n const handleScroll = () => {\n if (clickedIdRef.current) return;\n\n let currentId: string | null = null;\n for (const toc of tocs) {\n const id = toc.href.slice(1);\n const el = document.getElementById(id);\n if (!el) continue;\n\n const top = container ? el.offsetTop - container.scrollTop : el.getBoundingClientRect().top;\n\n if (top <= offset) {\n currentId = id;\n } else {\n break;\n }\n }\n\n if (currentId !== activeIdRef.current) {\n setActiveId(currentId);\n history.replaceState(null, \"\", currentId ? `#${currentId}` : \"#top\");\n }\n };\n\n handleScroll(); // set initial active on mount\n\n let throttleTimer: ReturnType<typeof setTimeout> | null = null;\n const listener =\n tocs.length > 30\n ? () => {\n if (throttleTimer) return;\n throttleTimer = setTimeout(() => {\n throttleTimer = null;\n handleScroll();\n }, 50);\n }\n : handleScroll;\n\n scrollTarget.addEventListener(\"scroll\", listener, { passive: true });\n\n return () => {\n scrollTarget.removeEventListener(\"scroll\", listener);\n if (throttleTimer) clearTimeout(throttleTimer);\n };\n }, [tocs, getAnchorOffset]);\n\n const handleLinkClick = useCallback((id: string) => {\n clickedIdRef.current = id;\n setActiveId(id);\n history.replaceState(null, \"\", `#${id}`);\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n clickTimerRef.current = setTimeout(() => {\n clickedIdRef.current = null;\n }, 1000);\n }, []);\n\n const handleScrollToTop = useCallback(() => {\n clickedIdRef.current = \"__top__\";\n setActiveId(null);\n history.replaceState(null, \"\", \"#top\");\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n clickTimerRef.current = setTimeout(() => {\n clickedIdRef.current = null;\n }, 1000);\n }, []);\n\n useEffect(() => {\n return () => {\n if (clickTimerRef.current) clearTimeout(clickTimerRef.current);\n };\n }, []);\n\n const activeItemRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (activeId && activeItemRef.current && !clickedIdRef.current) {\n activeItemRef.current.scrollIntoView({\n block: \"nearest\",\n behavior: \"smooth\",\n });\n }\n }, [activeId]);\n\n if (!tocs.length) return null;\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col gap-2\">\n <div className=\"flex shrink-0 items-center gap-2\">\n <ListIcon className=\"h-4 w-4\" />\n <h3 className=\"text-sm font-medium\">On this page</h3>\n </div>\n\n <div className=\"relative min-h-0 flex-1 overflow-y-auto pr-1\">\n <div className=\"relative text-sm\">\n <div className=\"bg-base-300 absolute top-0 left-0 h-full w-px\" />\n\n <div className=\"flex flex-col\">\n {tocs.map(({ href, level, text }) => {\n const id = href.slice(1);\n const isActive = activeId === id;\n const levelPadding = (level - 2) * 16;\n\n return (\n <div\n key={href}\n ref={isActive ? activeItemRef : undefined}\n className={cn(\n \"relative flex items-center transition-all duration-200\",\n isActive && \"bg-primary/5\"\n )}\n >\n <div\n className={cn(\n \"flex shrink-0 items-center px-1 py-2 transition-all duration-200\",\n isActive && \"border-primary -ml-px border-l-[3px]\"\n )}\n >\n <div\n className={cn(\n \"h-px transition-colors duration-200\",\n isActive ? \"bg-primary w-3\" : \"bg-base-300 w-2\"\n )}\n />\n <div\n className={cn(\n \"h-1.5 w-1.5 shrink-0 rounded-full transition-colors duration-300\",\n isActive ? \"bg-primary\" : \"bg-base-300\"\n )}\n />\n </div>\n\n <a\n href={href}\n onClick={(e) => {\n e.preventDefault();\n handleLinkClick(id);\n const el = document.getElementById(id);\n if (el) {\n // Manual scroll with the same offset the observer uses —\n // scrollIntoView ignores scroll-margin-top on iOS Safari\n // window-scroll, landing the heading under the sticky\n // mobile bar.\n const offset = getAnchorOffset();\n const scroller =\n window.innerWidth >= 1024\n ? document.getElementById(\"scroll-container\")\n : null;\n const elTop = el.getBoundingClientRect().top;\n if (scroller) {\n // Container scroll space: element offset within the\n // container minus the anchor offset (the container\n // itself may sit below the viewport top, e.g. under\n // the navbar).\n scroller.scrollTo({\n top:\n elTop -\n scroller.getBoundingClientRect().top +\n scroller.scrollTop -\n offset,\n behavior: \"smooth\",\n });\n } else {\n window.scrollTo({\n top: elTop + window.scrollY - offset,\n behavior: \"smooth\",\n });\n }\n }\n }}\n className={cn(\n \"flex flex-1 items-center py-2 transition-all duration-200\",\n isActive\n ? \"text-primary font-medium\"\n : \"text-base-content/60 hover:text-base-content\"\n )}\n style={{ paddingLeft: `${levelPadding + 6}px` }}\n >\n <span className=\"line-clamp-2 text-sm break-words\">{text}</span>\n </a>\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"mt-2 grid grid-cols-[28px_minmax(0,1fr)] items-start px-4 text-sm\">\n <div aria-hidden=\"true\" />\n <ScrollTo className=\"mt-0\" onScrollToTop={handleScrollToTop} />\n </div>\n </div>\n </div>\n );\n}\n","import { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport DocsBreadcrumb from \"../../components/Breadcrumb\";\nimport Pagination from \"../../components/Pagination\";\nimport { Typography } from \"../../components/Typography\";\nimport EditWith from \"../../components/EditWith\";\nimport { formatDate2 } from \"../../node/utils\";\nimport type { TocItem } from \"../../node/types\";\nimport { Footer } from \"../../components/Footer\";\nimport Toc from \"../../components/Toc\";\n\ninterface DocsPageProps {\n slug: string[];\n title: string;\n description?: string;\n date?: string;\n /** SSR'd MDX content HTML — rendered as its own root so client hydration\n * (separate island root) matches useId-based ids. */\n content: string;\n tocs: TocItem[];\n filePath: string;\n repoUrl?: string;\n /** Build-time slug keying into the bundled mdxModules manifest (client.ts). */\n mdxSlug?: string;\n /** Dev-only pre-compiled source for the legacy MDXRemote eval path. */\n compiledSource?: string;\n}\n\nexport default function DocsPage({\n slug,\n title,\n description,\n date,\n content,\n tocs,\n filePath,\n repoUrl,\n mdxSlug,\n compiledSource,\n}: DocsPageProps) {\n const pathname = slug.join(\"/\");\n const tocsJson = JSON.stringify(tocs);\n\n return (\n <div className=\"flex w-full flex-1 px-0 pb-4 lg:h-[calc(100vh-4rem)] lg:px-8 lg:pb-8\">\n <div\n id=\"scroll-container\"\n className=\"bg-base-100 border-base-300 relative flex w-full flex-col items-start rounded-b-3xl border shadow-md max-lg:scroll-p-54 lg:h-full lg:flex-row lg:overflow-y-auto lg:rounded-xl\"\n >\n {/* Mobile bar - island */}\n <div\n id=\"mobile-bar-island\"\n className=\"sticky top-0 z-50 w-full lg:hidden\"\n data-tocs={tocsJson}\n data-title={title}\n data-repo={repoUrl || \"\"}\n />\n\n <div className=\"flex w-full flex-col lg:flex-row 2xl:mx-auto 2xl:max-w-[1300px]\">\n <div\n className={`w-full min-w-0 ${tocs.length > 0 ? \"flex-[7]\" : \"mx-auto max-w-[820px]\"} px-4 py-6 lg:px-12 lg:py-10`}\n >\n <DocsBreadcrumb paths={slug} />\n <Typography>\n <h1 className=\"-mt-0.5 text-3xl\">{title}</h1>\n {description && (\n <p className=\"text-muted-foreground -mt-4 text-[16.5px]\">{description}</p>\n )}\n <div\n id=\"mdx-content-island\"\n data-mdx-slug={mdxSlug}\n dangerouslySetInnerHTML={{ __html: content }}\n />\n {compiledSource && (\n <script\n id=\"mdx-compiled-source\"\n type=\"application/json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify(compiledSource).replace(/<\\//g, \"\\\\u003C/\"),\n }}\n />\n )}\n <div className=\"border-base-300 my-8 flex items-center border-b-2 border-dashed\">\n <EditWith className=\"text-muted-foreground\" filePath={filePath} />\n {date && (\n <p className=\"text-muted-foreground ml-auto text-[13px]\">\n Last updated {formatDate2(date)}\n </p>\n )}\n </div>\n <Pagination\n pathname={pathname}\n prevIcon={<ChevronLeft className=\"h-3 w-3\" />}\n nextIcon={<ChevronRight className=\"h-3 w-3\" />}\n />\n <Footer />\n </Typography>\n </div>\n\n {/* Desktop TOC - SSR rendered */}\n {tocs.length > 0 && (\n <div\n id=\"toc-island\"\n data-tocs={tocsJson}\n className=\"sticky top-4 hidden h-[calc(100vh-8rem)] min-w-[240px] flex-[3] self-start lg:flex lg:px-4 lg:py-6\"\n >\n <Toc tocs={tocs} />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n","export function BackgroundBlobs() {\n return (\n <>\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute -top-40 left-1/2 -z-10 -translate-x-1/2 blur-3xl sm:-top-80\"\n >\n <div\n style={{\n clipPath:\n \"polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)\",\n }}\n className=\"from-primary to-accent h-[40rem] w-[80rem] bg-gradient-to-tr opacity-20\"\n />\n </div>\n\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute bottom-0 left-1/2 -z-10 translate-x-1/4 blur-3xl\"\n >\n <div\n style={{\n clipPath:\n \"polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)\",\n }}\n className=\"from-accent to-primary h-[30rem] w-[70rem] bg-gradient-to-tr opacity-20\"\n />\n </div>\n </>\n );\n}\n","import * as LucideIcons from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\n\n/**\n * Get Lucide icon component by name\n * Icon names must match Lucide's export names exactly (e.g., \"Zap\", \"BookOpen\", \"Search\")\n */\nexport function getLucideIcon(name: string): LucideIcon | null {\n if (!name) return null;\n const icon = (LucideIcons as unknown as Record<string, LucideIcon | undefined>)[name];\n return icon || null;\n}\n\n/**\n * Render Lucide icon component\n */\nexport function renderLucideIcon(name: string, className?: string) {\n const Icon = getLucideIcon(name);\n return Icon ? <Icon className={className} /> : null;\n}\n","\"use client\";\n\nimport type { Hero as HeroType, HeroAction } from \"../../node/types\";\nimport { cn } from \"../../node/utils\";\nimport { renderLucideIcon } from \"../Lucide\";\nimport { getSocialIcon } from \"../Social\";\n\ninterface HeroProps {\n hero: HeroType;\n className?: string;\n}\n\ninterface ActionButtonProps {\n action: HeroAction;\n}\n\nfunction isExternalLink(link: string): boolean {\n return /^https?:\\/\\//.test(link);\n}\n\nfunction renderActionButtonIcon(iconName: string | undefined, className?: string) {\n if (!iconName) return null;\n\n // Try Lucide icon first\n const lucideIcon = renderLucideIcon(iconName, className);\n if (lucideIcon) return lucideIcon;\n\n // Fallback to social icon\n const SocialIcon = getSocialIcon(iconName);\n if (SocialIcon) return <SocialIcon className={className} />;\n\n return null;\n}\n\nfunction ActionButton({ action }: ActionButtonProps) {\n const themeClasses = {\n primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/90\",\n ghost: \"bg-transparent text-muted-foreground border border-base-300 hover:bg-base-200\",\n };\n\n const isExternal = isExternalLink(action.link);\n\n return (\n <a\n href={action.link}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noopener noreferrer\" : undefined}\n className={cn(\n \"inline-flex items-center gap-2 rounded-lg px-6 py-3 text-sm font-medium transition-colors\",\n themeClasses[action.theme || \"primary\"]\n )}\n >\n {renderActionButtonIcon(action.icon, \"h-4 w-4\")}\n {action.text}\n </a>\n );\n}\n\nexport function Hero({ hero, className }: HeroProps) {\n const { tagline, headline, description, actions } = hero;\n\n return (\n <div className={cn(\"mx-auto max-w-4xl px-6 py-32 sm:py-44\", className)}>\n <div className=\"text-center\">\n {tagline && <p className=\"text-primary mb-4 text-lg font-semibold\">{tagline}</p>}\n <h1 className=\"text-5xl font-semibold tracking-tight text-balance sm:text-7xl\">\n {headline}\n </h1>\n {description && (\n <p className=\"text-muted-foreground mt-8 text-lg text-pretty sm:text-xl\">{description}</p>\n )}\n {actions && actions.length > 0 && (\n <div className=\"mt-10 flex flex-wrap items-center justify-center gap-4\">\n {actions.map((action, index) => (\n <ActionButton key={index} action={action} />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { HomeFeature } from \"../../node/types\";\nimport { cn } from \"../../node/utils\";\nimport { renderLucideIcon } from \"../Lucide\";\n\ninterface FeaturesProps {\n features: HomeFeature[];\n className?: string;\n}\n\ninterface FeatureCardProps {\n feature: HomeFeature;\n index: number;\n}\n\nfunction FeatureCard({ feature, index }: FeatureCardProps) {\n const Wrapper = feature.link ? \"a\" : \"div\";\n const wrapperProps = feature.link ? { href: feature.link } : {};\n\n // Use index-based patternId to avoid collisions\n const patternId = `grid-${index}`;\n\n return (\n <Wrapper\n {...wrapperProps}\n className={cn(\n \"border-base-200 bg-base-100 hover:border-primary/40 group relative overflow-hidden rounded-2xl border p-6 transition-all hover:shadow-lg\",\n feature.link && \"cursor-pointer\"\n )}\n >\n {/* Grid pattern background */}\n <svg\n className=\"absolute inset-0 h-full w-full\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ color: \"var(--color-primary)\" }}\n aria-hidden=\"true\"\n >\n <defs>\n <pattern id={patternId} width=\"40\" height=\"40\" patternUnits=\"userSpaceOnUse\">\n <path\n d=\"M 40 0 L 0 0 0 40\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"0.5\"\n opacity=\"0.15\"\n />\n </pattern>\n </defs>\n <rect width=\"100%\" height=\"100%\" fill={`url(#${patternId})`} />\n </svg>\n\n {/* Content */}\n <div className=\"relative z-10\">\n {feature.icon && (\n <div className=\"bg-primary/10 mb-4 inline-flex h-12 w-12 items-center justify-center rounded-lg\">\n {renderLucideIcon(feature.icon, \"h-6 w-6 text-primary\")}\n </div>\n )}\n <h3 className=\"mb-2 text-lg font-semibold\">{feature.title}</h3>\n <p className=\"text-muted-foreground text-sm\">{feature.description}</p>\n </div>\n </Wrapper>\n );\n}\n\nexport function Features({ features, className }: FeaturesProps) {\n if (!features || features.length === 0) return null;\n\n return (\n <div className={cn(\"mx-auto max-w-5xl px-6 pb-24\", className)}>\n <div className=\"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n {features.map((feature, index) => (\n <FeatureCard key={index} feature={feature} index={index} />\n ))}\n </div>\n </div>\n );\n}\n","import { BackgroundBlobs, Hero } from \"../components/home\";\nimport { servedBasePath } from \"../node/paths\";\n\nexport default function NotFoundPage() {\n return (\n <main className=\"bg-base-100 relative isolate flex min-h-screen w-full items-center justify-center overflow-hidden\">\n <BackgroundBlobs />\n <Hero\n hero={{\n headline: \"404\",\n description: \"Page not found\",\n actions: [{ text: \"Go to Docs\", link: `${servedBasePath()}/` }],\n }}\n />\n </main>\n );\n}\n","\"use client\";\n\nimport { Moon, Sun } from \"lucide-react\";\nimport { ThemeControllerToggle } from \"@docubook/ui-react/theme-controller\";\n\ninterface ThemeButtonsProps {\n className?: string;\n isDark: boolean;\n toggle?: (dark: boolean) => void;\n}\n\nfunction ThemeButtons({ className, isDark, toggle }: ThemeButtonsProps) {\n return (\n <div\n className={`border-base-600 dark:border-base-content/20 bg-base-100/50 flex items-center gap-1 rounded-full border p-0.5 transition-all ${className || \"\"}`}\n >\n <button\n type=\"button\"\n role=\"switch\"\n aria-label=\"Light mode\"\n aria-checked={!isDark}\n onClick={toggle ? () => toggle(false) : undefined}\n className=\"bg-primary cursor-pointer rounded-full p-0.5 transition-all dark:bg-transparent\"\n >\n <Sun\n className={`h-4 w-4 transition-colors ${\n !isDark ? \"text-primary-foreground\" : \"text-foreground\"\n }`}\n />\n </button>\n <button\n type=\"button\"\n role=\"switch\"\n aria-label=\"Dark mode\"\n aria-checked={isDark}\n onClick={toggle ? () => toggle(true) : undefined}\n className=\"dark:bg-primary cursor-pointer rounded-full p-0.5 transition-all\"\n >\n <Moon\n className={`h-4 w-4 transition-colors ${\n isDark ? \"text-primary-foreground\" : \"text-base-content/60\"\n }`}\n />\n </button>\n </div>\n );\n}\n\nexport function ThemeToggle({ className }: { className?: string }) {\n return (\n <ThemeControllerToggle lightTheme=\"light\" darkTheme=\"dark\">\n {({ isDark, toggle }) => (\n <ThemeButtons className={className} isDark={isDark} toggle={toggle} />\n )}\n </ThemeControllerToggle>\n );\n}\n","import { loadDocuConfig, resolveBasePath } from \"../node/paths\";\nimport { docsNavHref } from \"../node/utils\";\nimport { Hero, Features, BackgroundBlobs } from \"../components/home\";\nimport { ThemeToggle } from \"../components/Theme\";\nimport type { HomeFeature } from \"../node/types\";\n\nconst docuConfig = loadDocuConfig();\nconst basePath = resolveBasePath(docuConfig);\n\ninterface RouteContext {\n icon?: string;\n title?: string;\n description?: string;\n}\n\ninterface RouteItem {\n title: string;\n href: string;\n context?: RouteContext;\n items?: RouteItem[];\n}\n\nexport default function IndexPage() {\n const { meta, home } = docuConfig;\n const routes = (docuConfig.routes as RouteItem[]) || [];\n\n // Use home.features if configured, otherwise fallback to routes with context\n const features: HomeFeature[] =\n home?.features?.map((f) => ({\n ...f,\n link: f.link ? docsNavHref(f.link, basePath) : undefined,\n })) ||\n routes\n .filter((r) => r.context)\n .map((route) => ({\n icon: route.context?.icon,\n title: route.context?.title || route.title,\n description: route.context?.description || \"\",\n link: docsNavHref(`/docs${route.href}${route.items?.[0]?.href || \"\"}`, basePath),\n }));\n\n // Use home.hero if configured, otherwise fallback to meta\n const hero = home?.hero\n ? {\n ...home.hero,\n actions: home.hero.actions?.map((a) => ({\n ...a,\n link: docsNavHref(a.link, basePath),\n })),\n }\n : {\n headline: meta.title,\n description: meta.description,\n };\n\n return (\n <div className=\"bg-base-100 relative isolate min-h-screen overflow-hidden\">\n <div className=\"absolute top-4 right-4 z-10\">\n <div id=\"theme-toggle-island\">\n <ThemeToggle />\n </div>\n </div>\n\n <BackgroundBlobs />\n\n {/* Hero Section */}\n <Hero hero={hero} />\n\n {/* Features Section */}\n <Features features={features} />\n </div>\n );\n}\n","import { AnchorHTMLAttributes, ReactNode } from \"react\";\nimport { ArrowUpRight } from \"lucide-react\";\nimport { cn, isExternalUrl } from \"../node/utils\";\n\nexport interface AnchorProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href?: string;\n activeClassName?: string;\n activeWhen?: string | RegExp | ((pathname: string) => boolean);\n disabled?: boolean;\n children: ReactNode;\n className?: string;\n}\n\nexport default function Anchor({\n href = \"\",\n className = \"\",\n activeClassName = \"\",\n activeWhen,\n disabled = false,\n children,\n ...props\n}: AnchorProps) {\n const isActive = (() => {\n if (!activeWhen || typeof window === \"undefined\") return false;\n const pathname = window.location.pathname;\n if (typeof activeWhen === \"string\")\n return pathname === activeWhen || pathname.endsWith(activeWhen);\n if (activeWhen instanceof RegExp) return activeWhen.test(pathname);\n if (typeof activeWhen === \"function\") return activeWhen(pathname);\n return false;\n })();\n\n const isExternal = isExternalUrl(href);\n\n const activeClass = isActive ? activeClassName : \"\";\n const baseClasses = cn(\n \"hover:underline transition-colors\",\n className,\n activeClass,\n disabled && \"cursor-not-allowed opacity-50\"\n );\n\n if (disabled) {\n return <span className={baseClasses}>{children}</span>;\n }\n\n if (isExternal) {\n return (\n <a href={href} className={baseClasses} target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n {children}\n <ArrowUpRight className=\"ml-0.5 inline-block h-3.5 w-3.5\" />\n </a>\n );\n }\n\n return (\n <a href={href} className={baseClasses} {...props}>\n {children}\n </a>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useState,\n useRef,\n useEffect,\n useCallback,\n type ReactNode,\n} from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport Anchor from \"./Anchor\";\nimport type { DocuRoute } from \"../node/types\";\nimport { cn, docsHtmlHref } from \"../node/utils\";\nimport { config as docuConfig, basePath } from \"../node/client-routes\";\n\n/** Exclusive accordion for level >= 2 sidebar groups — opening one group\n * closes the previously open one. All level >= 2 groups default to closed\n * and expand only when the header is clicked. `open` is used to auto-expand\n * the group containing the active page. */\nexport const GroupAccordionContext = createContext<{\n openId: string | null;\n open: (id: string) => void;\n toggle: (id: string) => void;\n}>({ openId: null, open: () => {}, toggle: () => {} });\n\nexport function GroupAccordionProvider({ children }: { children: ReactNode }) {\n const [openId, setOpenId] = useState<string | null>(null);\n // Exclusive: expanding B closes A — only one group stays open at a time;\n // clicking the open group again collapses it.\n const open = useCallback((id: string) => setOpenId(id), []);\n const toggle = useCallback((id: string) => setOpenId((prev) => (prev === id ? null : id)), []);\n return (\n <GroupAccordionContext.Provider value={{ openId, open, toggle }}>\n {children}\n </GroupAccordionContext.Provider>\n );\n}\n\ninterface SublinkProps extends DocuRoute {\n level: number;\n onNavigate?: () => void;\n parentHref?: string;\n pathname?: string;\n}\n\nexport default function Sublink({\n title,\n href,\n items,\n noLink,\n level,\n onNavigate,\n parentHref = \"\",\n pathname: pathnameProp,\n}: SublinkProps) {\n const fullHref = parentHref ? `${parentHref}${href}` : `${basePath}${href}`;\n const currentPathname =\n pathnameProp || (typeof window !== \"undefined\" ? window.location.pathname : basePath);\n\n // Groups with children are exclusive accordions (default closed, expand on\n // click). In separator mode every nav item renders at level 0 (sections are\n // SidebarGroupHeader, not Sublinks), so depth can't tell them apart — the\n // mode does. In dropdown mode the top section is level 0 (stays open) and\n // everything deeper is an accordion.\n const isSeparator = docuConfig.sidebar?.context === \"separator\";\n const { openId, open, toggle } = useContext(GroupAccordionContext);\n const isAccordionGroup = Boolean(items) && (isSeparator || level >= 1);\n // Routes-tree level: separator mode renders every item at level 0 (sections\n // are SidebarGroupHeader), dropdown starts the context section at level 0.\n const treeLevel = level + (isSeparator ? 2 : 1);\n\n const [isOpen, setIsOpen] = useState(() => {\n if (isAccordionGroup) return false; // default closed — context controls it\n if (level === 0) return true; // top-level section stays open\n return false; // leaves\n });\n\n const effectiveOpen = isAccordionGroup ? openId === fullHref : isOpen;\n const handleToggle = () => {\n if (isAccordionGroup) toggle(fullHref);\n else setIsOpen((o) => !o);\n };\n\n // Auto-expand the accordion group that contains the active page — on mount\n // and whenever the current path changes. `open` is stable (useCallback), so\n // this only fires on real path changes; a manual collapse by the user is\n // respected until the path changes again.\n const isInsideActive = currentPathname.startsWith(fullHref) && currentPathname !== fullHref;\n useEffect(() => {\n if (isAccordionGroup && isInsideActive) open(fullHref);\n }, [isAccordionGroup, isInsideActive, fullHref, open]);\n\n // Shared padding based on nesting level\n const levelPadding = cn(level === 1 && \"pl-4\", level === 2 && \"pl-8\", level >= 3 && \"pl-12\");\n const isActive = currentPathname === fullHref || currentPathname === `${fullHref}.html`;\n const activeRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (isActive && activeRef.current) {\n activeRef.current.scrollIntoView({ block: \"nearest\" });\n }\n }, [isActive]);\n\n // Leaf node (no children)\n if (!items) {\n const link = (\n <Anchor\n href={docsHtmlHref(fullHref)}\n className=\"text-foreground hover:text-foreground/80 text-sm transition-colors\"\n activeClassName=\"text-primary font-medium\"\n activeWhen={(path) => path === fullHref || path === `${fullHref}.html`}\n onClick={onNavigate}\n >\n {title}\n </Anchor>\n );\n\n // Level 0: border handled by Menu.tsx wrapper\n // Level 1+: border at natural indented position, follows levelPadding\n if (level >= 1) {\n // Separator mode: active border overlaps at ul's edge\n // Each parent section adds its levelPadding to the offset\n if (docuConfig.sidebar?.context === \"separator\") {\n // Calculate accumulated offset from ul's edge to this item's natural position\n // Base: ul border(2px) + pl-3(12px) = 14px\n // Each parent section adds: level 1→16px, level 2→32px, level 3+→48px\n const sectionOffsets: Record<number, number> = { 1: 16, 2: 32 };\n let overlap = 14;\n for (let l = 1; l < level; l++) {\n overlap += sectionOffsets[l] ?? 48;\n }\n\n return (\n <div\n ref={activeRef}\n className={cn(\"border-l-2\", isActive ? \"border-primary\" : \"border-transparent\")}\n style={{ marginLeft: `-${overlap}px` }}\n >\n <div className={cn(\"py-1 pl-3\", levelPadding)}>{link}</div>\n </div>\n );\n }\n\n return (\n <div\n ref={activeRef}\n className={cn(\n \"py-1\",\n levelPadding,\n \"border-l-2\",\n isActive ? \"border-primary\" : \"border-base-300\"\n )}\n >\n {link}\n </div>\n );\n }\n\n return (\n <div ref={activeRef} className={cn(\"py-1\", levelPadding)}>\n {link}\n </div>\n );\n }\n\n // Section with children\n return (\n <div ref={isActive ? activeRef : undefined} className={cn(\"flex flex-col\", levelPadding)}>\n {/* Section header */}\n <button\n type=\"button\"\n onClick={handleToggle}\n className={cn(\n \"flex w-full cursor-pointer items-center justify-between py-1 text-left text-sm transition-colors\",\n // Only the top-level section label (routes-tree level 1) is bold.\n // Deeper groups (e.g. Search at level 2) are children that happen to\n // have items — style them like links, no header weight.\n noLink && treeLevel === 1\n ? \"text-base-content font-semibold\"\n : \"text-foreground hover:text-foreground/80\"\n )}\n >\n {noLink ? (\n <span>{title}</span>\n ) : (\n <Anchor\n href={docsHtmlHref(fullHref)}\n className=\"text-foreground hover:text-foreground/80 transition-colors\"\n activeClassName=\"text-primary\"\n activeWhen={(path) => path === fullHref || path === `${fullHref}.html`}\n onClick={onNavigate}\n >\n {title}\n </Anchor>\n )}\n <ChevronDown\n className={cn(\n \"text-base-content/40 h-4 w-4 shrink-0 transition-transform duration-200\",\n // Tree convention: closed = chevron pointing right (expandable),\n // open = pointing down — a 90° turn instead of the 180° flip.\n effectiveOpen ? \"rotate-0\" : \"-rotate-90\"\n )}\n />\n </button>\n\n {/* Children */}\n {effectiveOpen && (\n <div className=\"flex flex-col py-1\">\n {items.map((item) => (\n <Sublink\n key={`${fullHref}${item.href}`}\n {...item}\n href={item.href}\n level={level + 1}\n onNavigate={onNavigate}\n parentHref={fullHref}\n pathname={pathnameProp}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { renderLucideIcon } from \"./Lucide\";\n\ninterface SidebarGroupHeaderProps {\n icon?: string;\n title: string;\n}\n\nexport default function SidebarGroupHeader({ icon, title }: SidebarGroupHeaderProps) {\n return (\n <div className=\"sidebar-group-header mb-1.5 flex items-center gap-2.5 font-medium text-gray-900 dark:text-gray-200\">\n {icon && (\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center\">\n {renderLucideIcon(icon, \"h-3.5 w-3.5\")}\n </span>\n )}\n <h3 className=\"sidebar-title font-[inherit] text-[length:inherit] leading-[inherit]\">\n <span>{title}</span>\n </h3>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport Sublink, { GroupAccordionProvider } from \"./Sublink\";\nimport SidebarGroupHeader from \"./SidebarGroupHeader\";\nimport type { DocuRoute } from \"../node/types\";\nimport { cn } from \"../node/utils\";\nimport { config as docuConfig, basePath } from \"../node/client-routes\";\n\ninterface MenuProps {\n onNavigate?: () => void;\n className?: string;\n pathname?: string;\n routes?: DocuRoute[];\n}\n\nfunction getCurrentContext(path: string): string | undefined {\n if (!path.startsWith(basePath)) return undefined;\n const match = path.match(new RegExp(`^${basePath}/([^/]+)`));\n return match ? match[1] : undefined;\n}\n\nfunction getContextRoute(contextPath: string, routeList: DocuRoute[]): DocuRoute | undefined {\n return routeList.find((route) => {\n const normalizedHref = route.href.replace(/^\\/+|\\/+$/, \"\");\n return normalizedHref === contextPath;\n });\n}\n\nexport default function Menu({ onNavigate, className = \"\", pathname, routes = [] }: MenuProps) {\n const menuRoutes = routes;\n const [currentPath] = useState(\n () => pathname || (typeof window !== \"undefined\" ? window.location.pathname : basePath)\n );\n\n // Root deployment has no prefix to match against: every path belongs to docs.\n if (basePath.length > 0 && !currentPath.startsWith(basePath)) return null;\n\n const mode = docuConfig.sidebar?.context || \"dropdown\";\n const navProps = {\n \"aria-label\": \"Documentation navigation\" as const,\n className: cn(\"transition-all duration-200\", className),\n };\n\n // Shared nav item with border-left overlap wrapper\n const renderBorderItem = (item: DocuRoute, parentRouteHref: string, key: string) => {\n const fullHref = `${basePath}${parentRouteHref}${item.href}`;\n const isActive = currentPath === fullHref || currentPath === `${fullHref}.html`;\n return (\n <li key={key}>\n <div\n className={cn(\n \"-ml-[14px] border-l-2\",\n isActive ? \"border-primary\" : \"border-transparent\"\n )}\n >\n <div className=\"pl-3\">\n <Sublink\n {...item}\n href={item.href}\n level={0}\n onNavigate={onNavigate}\n parentHref={`${basePath}${parentRouteHref}`}\n />\n </div>\n </div>\n </li>\n );\n };\n\n const sharedUlClasses = \"border-base-300 flex flex-col gap-0.5 border-l-2 pb-0.5 pl-3 pt-0.5\";\n\n // Separator mode: render all context sections as group headers + nav items\n if (mode === \"separator\") {\n const contextRoutes = menuRoutes.filter((r) => r.context);\n\n // No context routes defined — fall back to flat list of all routes\n if (contextRoutes.length === 0) {\n return (\n <GroupAccordionProvider>\n <nav {...navProps}>\n <ul className={sharedUlClasses}>\n {menuRoutes.map((route) => renderBorderItem(route, \"\", route.href))}\n </ul>\n </nav>\n </GroupAccordionProvider>\n );\n }\n\n return (\n <GroupAccordionProvider>\n <nav {...navProps}>\n {contextRoutes.map((route, i) => (\n <div key={route.href} className={i > 0 ? \"mt-6 lg:mt-8\" : \"\"}>\n <SidebarGroupHeader\n icon={route.context?.icon}\n title={route.context?.title || route.title}\n />\n <ul className={sharedUlClasses}>\n {route.items?.map((item) => renderBorderItem(item, route.href, item.href))}\n </ul>\n </div>\n ))}\n </nav>\n </GroupAccordionProvider>\n );\n }\n\n // Dropdown mode: render only the active context section\n const isDocsRoot = currentPath === basePath || currentPath === `${basePath}/`;\n const currentContext = isDocsRoot\n ? menuRoutes[0]?.href.replace(/^\\/+|\\/+$/, \"\")\n : getCurrentContext(currentPath);\n\n const contextRoute =\n isDocsRoot && menuRoutes[0]\n ? currentContext\n ? getContextRoute(currentContext, menuRoutes)\n : menuRoutes[0]\n : currentContext\n ? getContextRoute(currentContext, menuRoutes)\n : undefined;\n\n if (!contextRoute) return null;\n\n return (\n <GroupAccordionProvider>\n <nav {...navProps}>\n <ul className=\"flex flex-col gap-0.5 py-4\">\n <li key={contextRoute.title}>\n <Sublink\n {...contextRoute}\n href={contextRoute.href}\n level={0}\n onNavigate={onNavigate}\n parentHref={basePath}\n />\n </li>\n </ul>\n </nav>\n </GroupAccordionProvider>\n );\n}\n","import React from \"react\";\nimport { loadDocuConfig, resolveBasePath } from \"../node/paths\";\nimport { docsNavHref } from \"../node/utils\";\nimport Menu from \"./Menu\";\n\nconst docuConfig = loadDocuConfig();\nconst basePath = resolveBasePath(docuConfig);\n\ninterface DocsLayoutProps {\n children?: React.ReactNode;\n repoUrl?: string;\n pathname?: string;\n}\n\nexport function DocsLayout({ children, repoUrl, pathname = basePath }: DocsLayoutProps) {\n return React.createElement(\n \"div\",\n { className: \"docs-layout flex flex-col min-h-screen w-full\" },\n React.createElement(\n \"div\",\n { className: \"flex flex-1 items-start w-full\" },\n React.createElement(\n \"aside\",\n {\n id: \"sidebar-island\",\n className:\n \"sticky top-0 hidden h-screen w-[280px] shrink-0 flex-col lg:flex border-r border-base-200 bg-base-100\",\n \"data-tocs\": \"[]\",\n \"data-title\": \"\",\n \"data-repo\": repoUrl || \"\",\n },\n // SSR sidebar content — Menu rendered server-side\n React.createElement(\n \"div\",\n { className: \"flex h-full flex-col overflow-y-auto px-4\" },\n React.createElement(Menu, { pathname, routes: docuConfig.routes || [] })\n )\n ),\n React.createElement(\n \"main\",\n { className: \"flex-1 min-w-0 min-h-screen flex flex-col\" },\n React.createElement(\n \"div\",\n { className: \"hidden lg:flex items-center justify-end gap-6 h-14 px-8\" },\n React.createElement(\n \"nav\",\n { className: \"flex items-center gap-6 text-sm font-medium text-base-content/80\" },\n ...(docuConfig.navbar?.menu || []).map((item: { title: string; href: string }) => {\n const isExternal = /^https?:\\/\\//.test(item.href);\n const href = isExternal ? item.href : docsNavHref(item.href, basePath);\n const isDocsActive = href === basePath;\n return React.createElement(\n \"a\",\n {\n key: item.title,\n href,\n className: `flex items-center gap-1 hover:text-base-content transition-colors${isDocsActive ? \" text-primary font-semibold\" : \"\"}`,\n ...(isExternal ? { target: \"_blank\", rel: \"noopener noreferrer\" } : {}),\n },\n item.title,\n isExternal\n ? React.createElement(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"14\",\n height: \"14\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: \"2\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n },\n React.createElement(\"path\", { d: \"M7 7h10v10\" }),\n React.createElement(\"path\", { d: \"M7 17 17 7\" })\n )\n : null\n );\n })\n )\n ),\n React.createElement(\"div\", { className: \"flex-1 w-full\" }, children)\n )\n )\n );\n}\n","const ESCAPE_RE = /[&<>\"']/g;\n\nconst ESCAPE_MAP: Record<string, string> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\n\n/**\n * Runtime-neutral HTML escaping — same character set as `Bun.escapeHTML`\n * (& < > \" '). Used by the shared HTML shell so Node/Deno entries never\n * touch the Bun global.\n */\nexport function escapeHtml(input: string): string {\n return input.replace(ESCAPE_RE, (ch) => ESCAPE_MAP[ch]);\n}\n","/**\n * Runtime-neutral HTML shell — identical templates to `html.ts` (Bun-only,\n * protected) but escaping via the pure `escapeHtml()` so it runs on\n * Node.js and Deno as well as Bun. Shared modules (`server-routes.ts`) and\n * the non-Bun entries import from here; `build.ts`/`server.ts` keep using\n * `html.ts` untouched.\n */\n\nimport { escapeHtml } from \"./escapeHtml\";\nimport { cspMeta } from \"./security\";\nimport { rebaseContentPath } from \"./utils\";\nimport { DEFAULT_BASE_PATH } from \"./paths\";\n\nimport type { SeoMeta } from \"./seo\";\n\nexport interface HtmlShellOptions {\n title: string;\n description: string;\n body: string;\n favicon: string;\n css: string;\n js?: string;\n nonce?: string;\n /**\n * Content-Security-Policy value (from `cspHeader()` in security.ts).\n * When provided, injects `<meta http-equiv=\"Content-Security-Policy\">` in `<head>`.\n * Essential for static deployment where HTTP headers cannot be set.\n */\n csp?: string;\n extraScripts?: string;\n themeCss?: string;\n /** Depth from document root (0=root, 1=subdir, 2=sub/subdir). Used for relative asset paths. */\n depth?: number;\n /** HTML strings to inject before `</head>` (from plugin `injectHead` hooks). */\n headExtra?: string[];\n /** HTML strings to inject before `</body>`, after the main script (from plugin `injectBody` hooks). */\n bodyExtra?: string[];\n /** SEO meta tags derived from config + frontmatter */\n seo?: SeoMeta;\n /** Root-absolute asset URLs (`/assets/...`). Required for pages served at\n * arbitrary paths (404 fallback) — relative depth is wrong there. */\n absoluteAssets?: boolean;\n /**\n * URL prefix the site is served under (`\"\"` at the deployment root, else\n * `/prefix` with no trailing slash). Used to re-base author-written content\n * paths (favicon, og-image) that carry the default `/docs` prefix. Bundle\n * assets live at the dist root (`/assets/`) and never take the prefix.\n * Defaults to `/docs` so callers that never pass a prefix keep the\n * historical output byte-identical.\n */\n basePath?: string;\n /**\n * Path the host serves the dist root under (`\"\"` at an origin root, `/repo`\n * for a GitHub Pages project site). Only root-absolute references need it —\n * relative ones already line up because pages and assets share it.\n */\n deployPath?: string;\n}\n\nexport function htmlShell(opts: HtmlShellOptions): string {\n const {\n title,\n description,\n body,\n favicon,\n css,\n js,\n nonce,\n csp,\n extraScripts,\n themeCss,\n depth = 0,\n headExtra,\n bodyExtra,\n absoluteAssets = false,\n basePath = DEFAULT_BASE_PATH,\n deployPath = \"\",\n } = opts;\n const nonceAttr = nonce ? ` nonce=\"${escapeHtml(nonce)}\"` : \"\";\n const themeStyle = themeCss ? `\\n <style${nonceAttr}>${escapeHtml(themeCss)}</style>` : \"\";\n const headInjection = headExtra?.length ? `\\n ${headExtra.join(\"\\n \")}` : \"\";\n const bodyInjection = bodyExtra?.length ? `\\n ${bodyExtra.join(\"\\n \")}` : \"\";\n const depthPrefix = depth === 0 ? \"\" : \"../\".repeat(depth);\n // Bundle assets (JS, CSS, chunks) are written to the dist root and are\n // independent of the docs prefix; pages climb out of the prefix with `../`.\n // Depth-independent URLs (404 fallback) still carry the host's deployment\n // path, which relative climbs cancel out.\n const assetPrefix = absoluteAssets ? `${deployPath}/assets/` : depthPrefix + \"assets/\";\n const clientScript = js\n ? `\\n <link rel=\"modulepreload\" href=\"${escapeHtml(assetPrefix + js)}\">\\n <script type=\"module\"${nonceAttr} src=\"${escapeHtml(assetPrefix + js)}\"></script>`\n : \"\";\n const resolvePath = (path: string) => {\n if (!path.startsWith(\"/\")) return path;\n // Author-written content paths (favicon, logo) are root-relative as they\n // appear on disk, e.g. \"/docs/assets/images/favicon.ico\". Re-base a leading\n // default prefix onto the configured one, otherwise the asset 404s at the\n // old path after a subpath change.\n const rebased = rebaseContentPath(path, basePath);\n return absoluteAssets ? `${deployPath}${rebased}` : depthPrefix + rebased.slice(1);\n };\n\n // Build SEO meta tags (OG, Twitter, canonical)\n let seoTags = \"\";\n if (opts.seo) {\n const s = opts.seo;\n const e = escapeHtml;\n seoTags = `\\n <meta property=\"og:title\" content=\"${e(title)}\" />\\n <meta property=\"og:description\" content=\"${e(description)}\" />\\n <meta property=\"og:url\" content=\"${e(s.url)}\" />\\n <meta property=\"og:type\" content=\"website\" />\\n <meta property=\"og:site_name\" content=\"${e(s.siteName)}\" />\\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\\n <link rel=\"canonical\" href=\"${e(s.url)}\" />`;\n if (s.image) {\n seoTags += `\\n <meta property=\"og:image\" content=\"${e(s.image)}\" />`;\n }\n }\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${escapeHtml(title)}</title>\n <meta name=\"description\" content=\"${escapeHtml(description)}\">\n ${favicon ? `<link rel=\"icon\" type=\"image/x-icon\" href=\"${escapeHtml(resolvePath(favicon))}\">` : \"\"}${themeStyle}\n <link rel=\"preload\" href=\"${escapeHtml(assetPrefix + css)}\" as=\"style\">\n <link rel=\"stylesheet\" href=\"${escapeHtml(assetPrefix + css)}\">\n ${csp ? `<meta http-equiv=\"Content-Security-Policy\" content=\"${escapeHtml(cspMeta(csp))}\">` : \"\"}\n ${seoTags}\n <script${nonceAttr}>try{if(localStorage.getItem(\"theme\")===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}</script>${headInjection}\n</head>\n<body>\n <div id=\"root\">${body}</div>${clientScript}${extraScripts ? `\\n ${extraScripts}` : \"\"}${bodyInjection}\n</body>\n</html>`;\n}\n\nexport function errorHtml(message: string, stack?: string): string {\n const msg = escapeHtml(message || \"Unknown error\");\n const st = escapeHtml(stack || \"\");\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <title>Server Error</title>\n <style>\n *{margin:0;padding:0;box-sizing:border-box}\n body{padding:2rem;font-family:ui-monospace,monospace;background:#1a1a2e;color:#e0e0e0}\n h1{color:#ff6b6b;font-size:1.5rem;margin-bottom:1rem}\n pre{background:#0d0d1a;border:1px solid #333;border-radius:8px;padding:1.5rem;overflow-x:auto;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word}\n .msg{color:#ff6b6b;font-weight:bold}\n </style>\n</head>\n <body>\n <h1>🔥 Server Error</h1>\n <pre><span class=\"msg\">${msg}</span>${st ? `\\n\\n${st}` : \"\"}</pre>\n </body>\n</html>`;\n}\n\nexport function hmrScript(nonce: string): string {\n return `<script nonce=\"${escapeHtml(nonce)}\">\n(function(){\n const es = new EventSource(\"/__hmr\");\n es.onmessage = function(e) {\n if (e.data === \"reload\") window.location.reload();\n };\n es.onerror = function() { es.close(); setTimeout(() => { window.location.reload(); }, 2000); };\n})();\n</script>`;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as loadDocuConfig } from "./paths-CHXABfXa.js";
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@docubook/flame",
|
|
4
|
-
version: "2.0
|
|
4
|
+
version: "2.1.0",
|
|
5
5
|
description: "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
|
|
6
6
|
type: "module",
|
|
7
7
|
types: "./.docu/node/plugin.ts",
|
|
@@ -304,4 +304,4 @@ function countRoutes(routes) {
|
|
|
304
304
|
//#endregion
|
|
305
305
|
export { logger as t };
|
|
306
306
|
|
|
307
|
-
//# sourceMappingURL=logger-
|
|
307
|
+
//# sourceMappingURL=logger-DYFD47f8.js.map
|