@ox-content/vite-plugin 2.32.0 → 2.34.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["path","path","escapeHtml","path","fs","path","extractTitle","fs","path","getUrlPath","resolveSiteName","oxContent","path","fs","renderPage","extractTitle","getUrlPath","path","fs","path","fs","require","createEmptyLintResult","escapeHtml","path"],"sources":["../src/markdown.ts","../src/environment.ts","../src/highlight.ts","../src/plugins/index.ts","../src/plugins/mermaid-protect.ts","../src/code-blocks.ts","../src/transform.ts","../src/docs.ts","../src/og-image/renderer.ts","../src/og-image/browser.ts","../src/og-image/template.ts","../src/og-image/cache.ts","../src/og-image/index.ts","../src/island/parse.ts","../src/ssg.ts","../src/search.ts","../src/dev-server.ts","../src/og-viewer.ts","../src/i18n.ts","../src/lint.ts","../src/lint-files.ts","../src/jsx-runtime.ts","../src/page-context.ts","../src/theme-renderer.ts","../src/index.ts"],"sourcesContent":["import * as path from \"path\";\n\nexport const DEFAULT_MARKDOWN_EXTENSIONS = [\".md\", \".markdown\", \".mdx\"] as const;\n\nexport function normalizeMarkdownExtensions(extensions?: readonly string[]): string[] {\n const values = extensions?.length ? extensions : DEFAULT_MARKDOWN_EXTENSIONS;\n const seen = new Set<string>();\n const normalized: string[] = [];\n\n for (const extension of values) {\n const value = extension.startsWith(\".\") ? extension : `.${extension}`;\n const key = value.toLowerCase();\n if (!seen.has(key)) {\n seen.add(key);\n normalized.push(value);\n }\n }\n\n return normalized;\n}\n\nexport function isMarkdownFilePath(\n filePath: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): boolean {\n const pathname = filePath.split(\"?\")[0].split(\"#\")[0].toLowerCase();\n return extensions.some((extension) => pathname.endsWith(extension.toLowerCase()));\n}\n\nexport function stripMarkdownExtension(\n filePath: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): string {\n const match = [...extensions]\n .sort((left, right) => right.length - left.length)\n .find((extension) => filePath.toLowerCase().endsWith(extension.toLowerCase()));\n\n return match ? filePath.slice(0, -match.length) : filePath;\n}\n\nexport function markdownGlobPattern(srcDir: string, extensions: readonly string[]): string {\n const suffixes = extensions.map((extension) => extension.replace(/^\\./, \"\"));\n if (suffixes.length === 1) {\n return path.join(srcDir, `**/*.${suffixes[0]}`);\n }\n return path.join(srcDir, `**/*.{${suffixes.join(\",\")}}`);\n}\n","/**\n * Vite Environment API integration for Ox Content.\n *\n * Creates a dedicated environment for Markdown processing,\n * enabling SSG-style rendering with separate client/server contexts.\n */\n\nimport type { EnvironmentOptions } from \"vite\";\nimport type { ResolvedOptions } from \"./types\";\nimport { isMarkdownFilePath } from \"./markdown\";\n\n/**\n * Creates the Markdown processing environment configuration.\n *\n * This environment is used for:\n * - Server-side rendering of Markdown files\n * - Static site generation\n * - Pre-rendering at build time\n *\n * @example\n * ```ts\n * // In your vite.config.ts\n * export default defineConfig({\n * environments: {\n * markdown: createMarkdownEnvironment({\n * srcDir: 'content',\n * gfm: true,\n * }),\n * },\n * });\n * ```\n */\nexport function createMarkdownEnvironment(options: ResolvedOptions): EnvironmentOptions {\n return {\n // Consumer type for this environment\n consumer: \"server\",\n\n // Build configuration\n build: {\n // Output to a separate directory\n outDir: `${options.outDir}/.markdown`,\n\n // Emit assets for SSG\n emitAssets: true,\n\n // Create manifest for asset tracking\n manifest: true,\n\n // SSR-like externalization\n rollupOptions: {\n external: [\n // Externalize Node.js built-ins\n /^node:/,\n // Externalize native modules\n /\\.node$/,\n ],\n },\n },\n\n // Resolve configuration\n resolve: {\n // Handle Markdown-like files\n extensions: options.extensions,\n\n // Conditions for module resolution\n conditions: [\"markdown\", \"node\", \"import\"],\n\n // Don't dedupe - each environment gets its own modules\n dedupe: [],\n },\n\n // Optimize dependencies\n optimizeDeps: {\n // Include ox-content dependencies\n include: [],\n // Exclude native modules\n exclude: [\"@ox-content/napi\"],\n },\n };\n}\n\n/**\n * Environment-specific module transformer.\n *\n * This is called during the transform phase to process\n * Markdown files within the environment context.\n */\nexport interface EnvironmentTransformContext {\n /**\n * Current environment name.\n */\n environment: string;\n\n /**\n * Whether we're in development mode.\n */\n isDev: boolean;\n\n /**\n * Whether this is a server-side render.\n */\n isSSR: boolean;\n\n /**\n * The resolved Vite config.\n */\n config: unknown;\n}\n\n/**\n * Creates environment-aware transform options.\n */\nexport function createTransformOptions(\n ctx: EnvironmentTransformContext,\n options: ResolvedOptions,\n): ResolvedOptions {\n return {\n ...options,\n // Adjust options based on environment\n highlight: ctx.isSSR ? options.highlight : false,\n ogImage: ctx.isSSR ? options.ogImage : false,\n };\n}\n\n/**\n * Runs pre-render for SSG.\n *\n * This function is called during build to pre-render all Markdown files.\n */\nexport async function prerender(\n files: string[],\n _options: ResolvedOptions,\n): Promise<Map<string, string>> {\n const results = new Map<string, string>();\n\n for (const file of files) {\n // In production, this would use the Ox Content parser\n // For now, we just mark the file as needing processing\n results.set(file, `/* Pre-rendered: ${file} */`);\n }\n\n return results;\n}\n\n/**\n * Environment plugin factory.\n *\n * Creates plugins specific to the Markdown environment.\n */\nexport function createEnvironmentPlugins(options: ResolvedOptions) {\n return [\n {\n name: \"ox-content:markdown-env\",\n\n // Only apply to markdown environment\n applyToEnvironment(name: string) {\n return name === \"markdown\";\n },\n\n // Transform within the environment\n transform(code: string, id: string) {\n if (!isMarkdownFilePath(id, options.extensions)) {\n return null;\n }\n\n // Environment-specific transformation\n return {\n code: `\n // Transformed in markdown environment\n ${code}\n `,\n };\n },\n },\n ];\n}\n","/**\n * Syntax highlighting with Shiki via rehype.\n */\n\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeStringify from \"rehype-stringify\";\nimport type { Root, Element } from \"hast\";\nimport {\n createHighlighter,\n type Highlighter,\n type BundledTheme,\n type LanguageRegistration,\n type ThemeRegistration,\n} from \"shiki\";\n\nconst BUILTIN_LANGS = [\n \"javascript\",\n \"typescript\",\n \"jsx\",\n \"tsx\",\n \"vue\",\n \"svelte\",\n \"html\",\n \"css\",\n \"scss\",\n \"json\",\n \"yaml\",\n \"markdown\",\n \"bash\",\n \"shell\",\n \"rust\",\n \"python\",\n \"go\",\n \"java\",\n \"c\",\n \"cpp\",\n \"sql\",\n \"graphql\",\n \"diff\",\n \"toml\",\n] as const;\n\n// Cache highlighters by theme + language registration set.\nconst highlighterCache = new Map<string, Promise<Highlighter>>();\n\n/**\n * Get or create the Shiki highlighter.\n */\nasync function getHighlighter(\n theme: string | ThemeRegistration,\n customLangs: LanguageRegistration[] = [],\n): Promise<Highlighter> {\n const { themeInput } = normalizeThemeInput(theme);\n const cacheKey = JSON.stringify({\n theme: themeInput,\n langs: customLangs,\n });\n\n let highlighterPromise = highlighterCache.get(cacheKey);\n if (!highlighterPromise) {\n highlighterPromise = createHighlighter({\n themes: [themeInput as BundledTheme | ThemeRegistration],\n langs: [...BUILTIN_LANGS, ...customLangs],\n });\n highlighterCache.set(cacheKey, highlighterPromise);\n }\n return highlighterPromise;\n}\n\nfunction normalizeThemeInput(theme: string | ThemeRegistration): {\n themeInput: string | ThemeRegistration;\n themeName: string;\n} {\n if (typeof theme === \"string\") {\n return {\n themeInput: theme,\n themeName: theme,\n };\n }\n\n const themeName = theme.name || \"ox-content-custom-theme\";\n return {\n themeInput: theme.name ? theme : { ...theme, name: themeName },\n themeName,\n };\n}\n\n/**\n * Rehype plugin for syntax highlighting with Shiki.\n */\nfunction rehypeShikiHighlight(options: {\n theme: string | ThemeRegistration;\n langs?: LanguageRegistration[];\n}) {\n const { theme, langs } = options;\n\n return async (tree: Root) => {\n const { themeName } = normalizeThemeInput(theme);\n const highlighter = await getHighlighter(theme, langs);\n\n const highlightBlockCode = (codeElement: Element): Element | null => {\n let lang = \"text\";\n const originalCodeClasses = normalizeClassName(codeElement.properties?.className);\n\n const langClass = originalCodeClasses.find((value) => value.startsWith(\"language-\"));\n if (langClass) {\n lang = langClass.replace(\"language-\", \"\");\n }\n\n const codeText = getTextContent(codeElement);\n\n try {\n const highlighted = highlighter.codeToHtml(codeText, {\n lang: lang as any,\n theme: themeName as BundledTheme,\n });\n\n const parsed = unified().use(rehypeParse, { fragment: true }).parse(highlighted);\n\n if (parsed.children[0]?.type === \"element\") {\n const highlightedPre = parsed.children[0];\n highlightedPre.properties ??= {};\n highlightedPre.properties[\"data-language\"] = lang;\n return highlightedPre;\n }\n } catch {\n // If highlighting fails, keep the original\n }\n\n return null;\n };\n\n const highlightInlineCode = (codeElement: Element): Element | null => {\n let lang = \"text\";\n const originalCodeClasses = normalizeClassName(codeElement.properties?.className);\n\n const langClass = originalCodeClasses.find((value) => value.startsWith(\"language-\"));\n if (!langClass) {\n return null;\n }\n\n lang = langClass.replace(\"language-\", \"\");\n const codeText = getTextContent(codeElement);\n\n try {\n const highlighted = highlighter.codeToHtml(codeText, {\n lang: lang as any,\n theme: themeName as BundledTheme,\n });\n\n const parsed = unified().use(rehypeParse, { fragment: true }).parse(highlighted);\n\n if (parsed.children[0]?.type === \"element\") {\n const highlightedPre = parsed.children[0];\n const highlightedCode = highlightedPre.children.find(\n (child): child is Element => child.type === \"element\" && child.tagName === \"code\",\n );\n\n if (highlightedCode) {\n highlightedCode.properties ??= {};\n const highlightedClasses = normalizeClassName(highlightedCode.properties.className);\n highlightedCode.properties.className = [\n ...new Set([...originalCodeClasses, ...highlightedClasses, \"shiki-inline\"]),\n ];\n highlightedCode.properties[\"data-language\"] = lang;\n return highlightedCode;\n }\n }\n } catch {\n // If highlighting fails, keep the original\n }\n\n return null;\n };\n\n // Find all pre > code elements\n const visit = async (node: Root | Element) => {\n if (\"children\" in node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n if (child.type === \"element\" && child.tagName === \"pre\") {\n const codeElement = child.children.find(\n (c): c is Element => c.type === \"element\" && c.tagName === \"code\",\n );\n\n if (codeElement) {\n const highlightedPre = highlightBlockCode(codeElement);\n if (highlightedPre) {\n node.children[i] = highlightedPre;\n }\n }\n } else if (child.type === \"element\" && child.tagName === \"code\") {\n const highlightedCode = highlightInlineCode(child);\n if (highlightedCode) {\n node.children[i] = highlightedCode;\n }\n } else if (child.type === \"element\") {\n await visit(child);\n }\n }\n }\n };\n\n await visit(tree);\n };\n}\n\n/**\n * Extract text content from a hast node.\n */\nfunction getTextContent(node: Element | Root): string {\n let text = \"\";\n\n if (\"children\" in node) {\n for (const child of node.children) {\n if (child.type === \"text\") {\n text += child.value;\n } else if (child.type === \"element\") {\n text += getTextContent(child);\n }\n }\n }\n\n return text;\n}\n\nfunction normalizeClassName(className: unknown): string[] {\n if (Array.isArray(className)) {\n return className.filter((value): value is string => typeof value === \"string\");\n }\n\n if (typeof className === \"string\" && className) {\n return className.split(/\\s+/).filter(Boolean);\n }\n\n return [];\n}\n\n/**\n * Apply syntax highlighting to HTML using Shiki.\n */\nexport async function highlightCode(\n html: string,\n theme: string | ThemeRegistration = \"github-dark\",\n langs: LanguageRegistration[] = [],\n): Promise<string> {\n const result = await unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeShikiHighlight, { theme, langs })\n .use(rehypeStringify)\n .process(html);\n\n return String(result);\n}\n","/**\n * ox-content Built-in Plugins\n *\n * All plugins are designed with No-JavaScript-First principle.\n * They generate static HTML at build time and require no client-side JS.\n */\n\nimport type { GitHubOptions } from \"./github\";\nimport type { MediaEmbedOptions } from \"./media\";\nimport type { OgpOptions } from \"./ogp\";\nimport type { PmOptions } from \"./pm\";\n\nexport {\n transformTabs,\n generateTabsCSS,\n resetTabGroupCounter,\n getTabGroupCounter,\n setTabGroupCounter,\n} from \"./tabs\";\n\nexport { transformPm, type PmOptions } from \"./pm\";\n\nexport { transformYouTube, extractVideoId, type YouTubeOptions } from \"./youtube\";\nexport { transformMediaEmbeds, type MediaEmbedOptions } from \"./media\";\n\nexport {\n transformGitHub,\n fetchRepoData,\n fetchGitHubSource,\n collectGitHubRepos,\n collectGitHubSources,\n prefetchGitHubRepos,\n prefetchGitHubSources,\n parseGitHubPermalink,\n parseGitHubLineRange,\n type GitHubRepoData,\n type GitHubSourceData,\n type GitHubSourceRef,\n type GitHubLineRange,\n type GitHubOptions,\n} from \"./github\";\n\nexport {\n transformOgp,\n fetchOgpData,\n collectOgpUrls,\n prefetchOgpData,\n type OgpData,\n type OgpOptions,\n} from \"./ogp\";\n\nexport { transformMermaidStatic, mermaidClientScript, type MermaidOptions } from \"./mermaid\";\n\n/**\n * Transform all plugin components in HTML.\n * Call this during SSG build to process all plugins at once.\n */\nexport interface TransformAllOptions {\n tabs?: boolean;\n /**\n * Expand `<pm>` package-manager blocks into install tabs. Pass an object to\n * opt in to synced groups (`{ sync: true }`); syncing is off by default.\n * @default false\n */\n pm?: boolean | PmOptions;\n youtube?: boolean;\n github?: boolean | GitHubOptions;\n ogp?: boolean | OgpOptions;\n openGraph?: boolean | OgpOptions;\n mermaid?: boolean;\n githubToken?: string;\n spotify?: boolean;\n stackBlitz?: boolean;\n twitter?: boolean;\n bluesky?: boolean;\n webContainer?: boolean;\n}\n\n/**\n * Transform all enabled plugins in HTML content.\n */\nexport async function transformAllPlugins(\n html: string,\n options: TransformAllOptions = {},\n): Promise<string> {\n const {\n tabs = true,\n pm = false,\n youtube = true,\n github = true,\n ogp,\n openGraph,\n mermaid = true,\n githubToken,\n spotify = false,\n stackBlitz = false,\n twitter = false,\n bluesky = false,\n webContainer = false,\n } = options;\n\n let result = html;\n const ogpOptions = openGraph ?? ogp ?? true;\n\n // Order matters: process in dependency order\n\n // 1. Tabs (no external dependencies)\n if (tabs) {\n const { transformTabs } = await import(\"./tabs\");\n result = await transformTabs(result);\n }\n\n // 1b. Package-manager tabs (no external dependencies). Shares the tab-group\n // counter with the tabs transform, so it runs right after it. Syncing is\n // opt-in via `{ pm: { sync: true } }` and off by default.\n if (pm) {\n const { transformPm } = await import(\"./pm\");\n result = await transformPm(result, typeof pm === \"object\" ? pm : {});\n }\n\n // 2. YouTube (no external dependencies)\n if (youtube) {\n const { transformYouTube } = await import(\"./youtube\");\n result = await transformYouTube(result);\n }\n\n // 3. GitHub (requires API calls)\n if (github !== false) {\n const { transformGitHub } = await import(\"./github\");\n const options = typeof github === \"object\" ? github : {};\n result = await transformGitHub(result, undefined, { token: githubToken, ...options });\n }\n\n // 4. OGP (requires fetch calls)\n if (ogpOptions !== false) {\n const { transformOgp } = await import(\"./ogp\");\n result = await transformOgp(\n result,\n undefined,\n typeof ogpOptions === \"object\" ? ogpOptions : {},\n );\n }\n\n const mediaOptions = { spotify, stackBlitz, twitter, bluesky, webContainer };\n if (Object.values(mediaOptions).some(Boolean)) {\n const { transformMediaEmbeds } = await import(\"./media\");\n result = await transformMediaEmbeds(result, mediaOptions);\n }\n\n // 5. Mermaid (requires mermaid library)\n if (mermaid) {\n const { transformMermaidStatic } = await import(\"./mermaid\");\n result = await transformMermaidStatic(result);\n }\n\n return result;\n}\n\n/**\n * Transform built-in embed components in HTML content.\n */\nexport async function transformBuiltinEmbeds(\n html: string,\n options: {\n github: GitHubOptions | false;\n openGraph: OgpOptions | false;\n pm?: PmOptions | false;\n spotify?: boolean;\n stackBlitz?: boolean;\n twitter?: boolean;\n bluesky?: boolean;\n webContainer?: boolean;\n },\n): Promise<string> {\n let result = html;\n\n if (options.github) {\n const { transformGitHub } = await import(\"./github\");\n result = await transformGitHub(result, undefined, {\n token: process.env.GITHUB_TOKEN,\n ...options.github,\n });\n }\n\n if (options.openGraph) {\n const { transformOgp } = await import(\"./ogp\");\n result = await transformOgp(result, undefined, options.openGraph);\n }\n\n if (options.pm) {\n const { transformPm } = await import(\"./pm\");\n result = await transformPm(result, typeof options.pm === \"object\" ? options.pm : {});\n }\n\n const mediaOptions: MediaEmbedOptions = {\n spotify: options.spotify,\n stackBlitz: options.stackBlitz,\n twitter: options.twitter,\n bluesky: options.bluesky,\n webContainer: options.webContainer,\n };\n if (Object.values(mediaOptions).some(Boolean)) {\n const { transformMediaEmbeds } = await import(\"./media\");\n result = await transformMediaEmbeds(result, mediaOptions);\n }\n\n return result;\n}\n","/**\n * Protects mermaid SVG content from rehype HTML5 parser corruption.\n *\n * rehypeParse + rehypeStringify converts `<br />` in SVG foreignObject\n * to `<br></br>`, which HTML5 interprets as 2 <br> elements.\n * Each rehype pass doubles them: 1 → 2 → 4 → 8 → 16.\n *\n * This module extracts ox-mermaid SVG blocks into placeholders before\n * rehype processing and restores them after.\n */\n\nexport interface MermaidSvgProtection {\n html: string;\n svgs: Map<string, string>;\n}\n\n/**\n * Extract `<div class=\"ox-mermaid\">...</div>` blocks and replace\n * with HTML comment placeholders that rehype will preserve.\n */\nexport function protectMermaidSvgs(html: string): MermaidSvgProtection {\n const svgs = new Map<string, string>();\n let result = html;\n let idx = 0;\n\n while (true) {\n const marker = `<div class=\"ox-mermaid\">`;\n const start = result.indexOf(marker, idx);\n if (start === -1) break;\n\n // Find the matching </div> by counting nested divs\n let depth = 0;\n let pos = start;\n let endPos = -1;\n\n while (pos < result.length) {\n const openIdx = result.indexOf(\"<div\", pos);\n const closeIdx = result.indexOf(\"</div>\", pos);\n if (closeIdx === -1) break;\n\n if (openIdx !== -1 && openIdx < closeIdx) {\n depth++;\n pos = openIdx + 4;\n } else {\n depth--;\n if (depth === 0) {\n endPos = closeIdx + 6;\n break;\n }\n pos = closeIdx + 6;\n }\n }\n\n if (endPos === -1) break;\n\n const svgContent = result.substring(start, endPos);\n const placeholder = `<!--ox-mermaid-${svgs.size}-->`;\n svgs.set(placeholder, svgContent);\n result = result.substring(0, start) + placeholder + result.substring(endPos);\n idx = start + placeholder.length;\n }\n\n return { html: result, svgs };\n}\n\n/**\n * Restore protected mermaid SVG blocks from placeholders.\n */\nexport function restoreMermaidSvgs(html: string, svgs: Map<string, string>): string {\n if (svgs.size === 0) {\n return html;\n }\n // Single pass over the HTML instead of one full `String.replace` scan per\n // placeholder (O(svgs × html) → O(html)). The function replacer also avoids\n // the `$`-pattern interpretation that the string form of `replace` applies\n // to the SVG replacement content.\n return html.replace(/<!--ox-mermaid-\\d+-->/g, (placeholder) => {\n const content = svgs.get(placeholder);\n return content !== undefined ? content : placeholder;\n });\n}\n","import { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { execFile } from \"node:child_process\";\nimport { importNapiModule } from \"./napi\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface ExtractedCodeBlock {\n language: string;\n meta: string;\n code: string;\n startLine: number;\n endLine: number;\n}\n\nexport interface CodeBlockDiagnostic {\n ruleId: string;\n severity: \"error\" | \"warning\" | \"info\";\n message: string;\n line: number;\n column: number;\n endLine: number;\n endColumn: number;\n language?: string;\n}\n\nexport interface CodeBlockLintOptions {\n languages?: string[];\n requireLanguage?: boolean;\n trailingSpaces?: boolean;\n}\n\nexport interface DocsTestOptions {\n languages?: string[];\n requireMeta?: boolean;\n}\n\nexport interface TypecheckCodeBlockOptions {\n languages?: string[];\n requireMeta?: boolean;\n tsgoCommand?: string;\n}\n\nexport async function extractCodeBlocks(source: string): Promise<ExtractedCodeBlock[]> {\n const mod = await importNapiModule();\n return mod.extractCodeBlocks(source).map(normalizeBlock);\n}\n\nexport async function lintCodeBlocks(\n source: string,\n options: CodeBlockLintOptions = {},\n): Promise<CodeBlockDiagnostic[]> {\n const mod = await importNapiModule();\n return mod\n .lintCodeBlocks(source, {\n enabled: true,\n languages: options.languages,\n requireLanguage: options.requireLanguage,\n trailingSpaces: options.trailingSpaces,\n })\n .map(normalizeDiagnostic);\n}\n\nexport async function extractDocsTests(\n source: string,\n options: DocsTestOptions = {},\n): Promise<ExtractedCodeBlock[]> {\n const mod = await importNapiModule();\n return mod\n .extractDocsTests(source, {\n enabled: true,\n languages: options.languages,\n requireMeta: options.requireMeta,\n })\n .map(normalizeBlock);\n}\n\nexport async function typecheckCodeBlocks(\n source: string,\n options: TypecheckCodeBlockOptions = {},\n): Promise<CodeBlockDiagnostic[]> {\n if (!source.includes(\"```\")) {\n return [];\n }\n\n const languages = new Set(\n (options.languages ?? [\"ts\", \"tsx\"]).map((language) => language.toLowerCase()),\n );\n const blocks = (await extractCodeBlocks(source)).filter((block) => {\n if (!languages.has(block.language.toLowerCase())) {\n return false;\n }\n return options.requireMeta === false || hasTypecheckMeta(block.meta);\n });\n if (blocks.length === 0) {\n return [];\n }\n\n const temp = await mkdtemp(join(tmpdir(), \"ox-content-code-blocks-\"));\n try {\n const files: string[] = [];\n await Promise.all(\n blocks.map(async (block, index) => {\n const extension = block.language.toLowerCase() === \"tsx\" ? \"tsx\" : \"ts\";\n const file = join(temp, `snippet-${index}.${extension}`);\n files.push(file);\n await writeFile(file, block.code);\n }),\n );\n\n try {\n await execFileAsync(\n options.tsgoCommand ?? \"tsgo\",\n [\"--noEmit\", \"--pretty\", \"false\", ...files],\n {\n cwd: process.cwd(),\n maxBuffer: 1024 * 1024 * 4,\n },\n );\n return [];\n } catch (error) {\n const output = commandOutput(error);\n return [\n {\n ruleId: \"code-block-typecheck\",\n severity: \"error\",\n message: output || \"TypeScript code block type-checking failed.\",\n line: blocks[0]?.startLine ?? 1,\n column: 1,\n endLine: blocks[0]?.startLine ?? 1,\n endColumn: 1,\n language: \"ts\",\n },\n ];\n }\n } finally {\n await rm(temp, { recursive: true, force: true });\n }\n}\n\nfunction hasTypecheckMeta(meta: string): boolean {\n return meta\n .split(/\\s+/)\n .some(\n (token) => token === \"typecheck\" || token === \"twoslash\" || token.startsWith(\"typecheck=\"),\n );\n}\n\nfunction commandOutput(error: unknown): string {\n if (!error || typeof error !== \"object\") {\n return \"\";\n }\n const value = error as { stdout?: unknown; stderr?: unknown; message?: unknown };\n return [value.stdout, value.stderr, value.message]\n .filter((part): part is string => typeof part === \"string\" && part.trim().length > 0)\n .join(\"\\n\")\n .trim();\n}\n\nfunction normalizeBlock(block: {\n language: string;\n meta: string;\n code: string;\n startLine: number;\n endLine: number;\n}): ExtractedCodeBlock {\n return block;\n}\n\nfunction normalizeDiagnostic(diagnostic: {\n ruleId: string;\n severity: string;\n message: string;\n line: number;\n column: number;\n endLine: number;\n endColumn: number;\n language?: string;\n}): CodeBlockDiagnostic {\n return {\n ...diagnostic,\n severity:\n diagnostic.severity === \"error\" || diagnostic.severity === \"info\"\n ? diagnostic.severity\n : \"warning\",\n };\n}\n","/**\n * Markdown Transformation Engine\n *\n * This module handles the complete transformation pipeline for Markdown files,\n * converting raw Markdown content into JavaScript modules that can be imported\n * by web applications. The transformation process includes:\n *\n * 1. **Parsing**: Uses Rust-based parser via NAPI bindings for high performance\n * 2. **Rendering**: Converts parsed AST to semantic HTML\n * 3. **Enhancement**: Applies syntax highlighting, Mermaid diagram rendering, etc.\n * 4. **Code Generation**: Generates JavaScript/TypeScript module code\n *\n * The generated modules export:\n * - `html`: Rendered HTML content\n * - `frontmatter`: Parsed YAML metadata\n * - `toc`: Hierarchical table of contents\n * - `render`: Client-side render function for dynamic updates\n *\n * @example\n * ```typescript\n * import { transformMarkdown } from './transform';\n *\n * const content = await transformMarkdown(\n * '# Hello\\n\\nWorld',\n * 'path/to/file.md',\n * resolvedOptions\n * );\n *\n * console.log(content.html); // '<h1>Hello</h1><p>World</p>'\n * console.log(content.toc); // [{ depth: 1, text: 'Hello', slug: 'hello', children: [] }]\n * ```\n */\n\nimport type { ResolvedOptions, TransformResult, TocEntry } from \"./types\";\nimport { highlightCode } from \"./highlight\";\nimport { importNapiModule } from \"./napi\";\nimport { transformMermaidStatic } from \"./plugins/mermaid\";\nimport { transformBuiltinEmbeds } from \"./plugins\";\nimport { protectMermaidSvgs, restoreMermaidSvgs } from \"./plugins/mermaid-protect\";\nimport { typecheckCodeBlocks } from \"./code-blocks\";\n\n/**\n * NAPI bindings for Rust-based Markdown processing.\n *\n * Provides access to compiled Rust functions for high-performance\n * Markdown parsing and rendering operations.\n */\ninterface NapiBindings {\n /**\n * Simple Markdown parser and renderer in one step.\n * Faster for simple use cases but lacks advanced features.\n *\n * @param source - Raw Markdown content\n * @param options - Parser configuration (GFM flag)\n * @returns Rendered HTML and parsing errors\n */\n parseAndRender: (\n source: string,\n options?: { gfm?: boolean },\n ) => { html: string; errors: string[] };\n\n /**\n * Full-featured Markdown transformation pipeline.\n * Handles frontmatter extraction, TOC generation, and advanced parsing.\n *\n * @param source - Raw Markdown content (may include frontmatter)\n * @param options - Comprehensive transformation options\n * @returns Transformed result with HTML, metadata, and TOC\n */\n transform: (\n source: string,\n options?: JsTransformOptions,\n ) => {\n html: string;\n frontmatter: string;\n toc: Array<{ depth: number; text: string; slug: string; children?: TocEntry[] }>;\n errors: string[];\n };\n\n /**\n * Generates an OG image as SVG.\n *\n * @param data - OG image data (title, description, etc.)\n * @param config - Optional OG image configuration\n * @returns SVG string\n */\n generateOgImageSvg: (data: OgImageData, config?: OgImageConfig) => string;\n\n /**\n * Restores code block metadata after JavaScript-side syntax highlighting.\n *\n * @param originalHtml - HTML before syntax highlighting\n * @param highlightedHtml - HTML after Shiki highlighting\n * @returns Highlighted HTML with original code block metadata reapplied\n */\n mergeHighlightedCodeBlocks: (originalHtml: string, highlightedHtml: string) => string;\n\n sanitizeHtml: (html: string, options?: JsSanitizeOptions) => string;\n\n lintCodeBlocks: (source: string, options?: JsCodeBlockLintOptions) => JsCodeBlockDiagnostic[];\n}\n\n/**\n * OG image data for generating social media preview images.\n */\nexport interface OgImageData {\n /** Page title */\n title: string;\n /** Page description */\n description?: string;\n /** Site name */\n siteName?: string;\n /** Author name */\n author?: string;\n}\n\n/**\n * OG image configuration.\n */\nexport interface OgImageConfig {\n /** Image width in pixels */\n width?: number;\n /** Image height in pixels */\n height?: number;\n /** Background color (hex) */\n backgroundColor?: string;\n /** Text color (hex) */\n textColor?: string;\n /** Title font size */\n titleFontSize?: number;\n /** Description font size */\n descriptionFontSize?: number;\n}\n\n/**\n * Options for Rust-based Markdown transformation.\n *\n * Controls which Markdown extensions and features are enabled\n * during parsing and rendering.\n */\ninterface JsTransformOptions {\n /**\n * Enable GitHub Flavored Markdown extensions.\n * Includes tables, task lists, strikethrough, and autolinks.\n * @default false\n */\n gfm?: boolean;\n\n /**\n * Enable footnotes syntax ([^1]: definition).\n * @default false\n */\n footnotes?: boolean;\n\n /**\n * Enable task list syntax (- [ ] unchecked, - [x] checked).\n * @default false\n */\n taskLists?: boolean;\n\n /**\n * Enable table rendering (GFM extension).\n * Requires GFM to be enabled for full functionality.\n * @default false\n */\n tables?: boolean;\n\n /**\n * Enable strikethrough syntax (~~text~~).\n * Requires GFM to be enabled.\n * @default false\n */\n strikethrough?: boolean;\n\n /**\n * Enable automatic link conversion (URLs become clickable).\n * @default false\n */\n autolinks?: boolean;\n\n /**\n * Parse YAML frontmatter before transforming.\n * @default true\n */\n frontmatter?: boolean;\n\n /**\n * Maximum heading depth for table of contents.\n * Headings deeper than this level are excluded from TOC.\n * @default 3\n * @min 1\n * @max 6\n */\n tocMaxDepth?: number;\n\n /**\n * Convert `.md` links to `.html` links for SSG output.\n * @default false\n */\n convertMdLinks?: boolean;\n\n /**\n * Base URL for absolute link conversion (e.g., \"/\" or \"/docs/\").\n * @default \"/\"\n */\n baseUrl?: string;\n\n /**\n * Source file path for relative link resolution.\n * Used to determine if the current file is an index file.\n */\n sourcePath?: string;\n\n /**\n * Enable line annotations for code blocks using fence meta.\n * @default false\n */\n codeAnnotations?: boolean;\n\n /**\n * Fence meta key used to read code annotations.\n * @default \"annotate\"\n */\n codeAnnotationMetaKey?: string;\n\n /**\n * Code annotation syntax mode.\n * @default \"attribute\"\n */\n codeAnnotationSyntax?: \"attribute\" | \"vitepress\" | \"both\";\n\n /**\n * Enable line numbers for all code blocks by default.\n * @default false\n */\n codeAnnotationDefaultLineNumbers?: boolean;\n\n wikiLinks?: {\n enabled?: boolean;\n baseUrl?: string;\n };\n\n emojiShortcodes?: {\n enabled?: boolean;\n custom?: Record<string, string>;\n };\n\n attributes?: {\n enabled?: boolean;\n };\n\n cjkEmphasis?: boolean;\n\n codeImports?: {\n enabled?: boolean;\n rootDir?: string;\n };\n\n sanitize?: JsSanitizeOptions;\n\n editThisPage?: {\n enabled?: boolean;\n repoUrl?: string;\n branch?: string;\n rootDir?: string;\n label?: string;\n };\n}\n\ninterface JsSanitizeOptions {\n enabled?: boolean;\n allowedTags?: string[];\n allowedAttributes?: string[];\n allowedUrlSchemes?: string[];\n}\n\ninterface JsCodeBlockLintOptions {\n enabled?: boolean;\n languages?: string[];\n requireLanguage?: boolean;\n trailingSpaces?: boolean;\n}\n\ninterface JsCodeBlockDiagnostic {\n ruleId: string;\n severity: string;\n message: string;\n line: number;\n column: number;\n endLine: number;\n endColumn: number;\n language?: string;\n}\n\n/**\n * Cached NAPI bindings instance.\n * Loaded on first use and reused for subsequent transformations.\n * @internal\n */\nlet napiBindings: NapiBindings | null | undefined;\n\n/**\n * Flag to prevent repeated NAPI loading attempts.\n * Set to true after first load attempt (success or failure).\n * @internal\n */\nlet napiLoadAttempted = false;\n\n/**\n * Lazily loads and caches NAPI bindings.\n *\n * This function uses lazy loading to defer the import of NAPI bindings\n * until they're actually needed. The bindings are loaded only once and\n * cached for subsequent uses. If loading fails (e.g., bindings not built),\n * the failure is cached to avoid repeated load attempts.\n *\n * ## Performance Considerations\n *\n * The first call to this function may have a slight performance penalty\n * due to module loading. Subsequent calls use the cached result and are\n * essentially zero-cost.\n *\n * ## Error Handling\n *\n * If NAPI bindings are not available (not built, wrong architecture, etc.),\n * this function returns `null`. The caller should handle this gracefully\n * or provide fallback behavior.\n *\n * @returns Promise resolving to NAPI bindings or null if unavailable\n *\n * @example\n * ```typescript\n * // Simple check with fallback\n * const napi = await loadNapiBindings();\n * if (!napi) {\n * console.warn('NAPI bindings not available, using fallback');\n * return fallbackRender(content);\n * }\n *\n * // Use Rust implementation\n * const result = napi.transform(content, { gfm: true });\n * ```\n *\n * @internal\n */\nasync function loadNapiBindings(): Promise<NapiBindings | null> {\n // Return cached result (success or failure)\n if (napiLoadAttempted) {\n return napiBindings ?? null;\n }\n\n // Mark attempt as made to prevent retry loops\n napiLoadAttempted = true;\n\n try {\n // Dynamic import to handle cases where NAPI isn't built\n const mod = await importNapiModule();\n napiBindings = mod;\n return mod;\n } catch (error) {\n // NAPI not available (not built, missing dependencies, etc.)\n // Log for debugging but don't throw - allow graceful degradation\n if (process.env.DEBUG) {\n console.debug(\"[ox-content] NAPI bindings load failed:\", error);\n }\n napiBindings = null;\n return null;\n }\n}\n\n/**\n * Transforms Markdown content into a JavaScript module.\n *\n * This is the primary entry point for transforming Markdown files. It handles\n * the complete transformation pipeline including parsing, rendering, syntax\n * highlighting, and code generation.\n *\n * ## Pipeline Steps\n *\n * 1. **Parse & Render**: Uses Rust-based parser via NAPI for high performance\n * 2. **Extract Metadata**: Parses YAML frontmatter and generates table of contents\n * 3. **Enhance HTML**: Applies syntax highlighting and Mermaid diagram rendering\n * 4. **Generate Code**: Creates importable JavaScript module\n *\n * ## Generated Module Exports\n *\n * - `html` (string): Rendered HTML content with all enhancements applied\n * - `frontmatter` (object): Parsed YAML frontmatter as JavaScript object\n * - `toc` (array): Hierarchical table of contents entries\n * - `render` (function): Client-side render function for dynamic updates\n *\n * ## Markdown Features Supported\n *\n * The supported features depend on parser options:\n * - **Commonmark**: Headings, paragraphs, lists, code blocks, links, images\n * - **GFM Extensions**: Tables, task lists, strikethrough, autolinks\n * - **Enhancements**: Syntax highlighting, Mermaid diagrams, TOC generation\n * - **Metadata**: YAML frontmatter parsing\n *\n * ## Performance\n *\n * Uses Rust-based parsing via NAPI bindings for optimal performance. Falls back\n * gracefully if Rust bindings are unavailable.\n *\n * @param source - Raw Markdown source code (may include YAML frontmatter)\n * @param filePath - File path for source attribution and relative link resolution\n * @param options - Resolved plugin options controlling transformation behavior\n *\n * @returns Promise resolving to transformation result with HTML and metadata\n *\n * @throws Error if NAPI bindings are unavailable (can be handled gracefully)\n *\n * @example\n * ```typescript\n * import { transformMarkdown } from './transform';\n * import { resolveOptions } from './index';\n *\n * // Transform a Markdown file with YAML frontmatter\n * const markdown = `---\n * title: Getting Started\n * author: john\n * ---\n *\n * # Getting Started\n *\n * Welcome! This guide explains [transformMarkdown] function.\n *\n * ## Installation\n *\n * \\`\\`\\`bash\n * npm install @ox-content/vite-plugin\n * \\`\\`\\`\n * `;\n *\n * const options = resolveOptions({\n * highlight: true,\n * highlightTheme: 'github-dark',\n * toc: true,\n * gfm: true,\n * mermaid: true,\n * });\n *\n * const result = await transformMarkdown(markdown, 'docs/getting-started.md', options);\n *\n * // Generated module exports\n * console.log(result.html); // Rendered HTML with syntax highlighting\n * console.log(result.frontmatter); // { title: 'Getting Started', author: 'john' }\n * console.log(result.toc); // [{ depth: 1, text: 'Getting Started', ... }]\n * console.log(result.code); // ES module export statement\n * ```\n */\n/**\n * SSG-specific transform options.\n */\nexport interface SsgTransformOptions {\n /** Convert `.md` links to `.html` links */\n convertMdLinks?: boolean;\n /** Base URL for absolute link conversion */\n baseUrl?: string;\n /** Source file path for relative link resolution */\n sourcePath?: string;\n}\n\nexport async function transformMarkdown(\n source: string,\n filePath: string,\n options: ResolvedOptions,\n ssgOptions?: SsgTransformOptions,\n): Promise<TransformResult> {\n const napi = await loadNapiBindings();\n\n if (!napi) {\n throw new Error(\n \"[ox-content] NAPI bindings not available. Please ensure @ox-content/napi is built.\",\n );\n }\n\n // Use Rust-based transformation, including frontmatter preparation.\n runCodeBlockLint(source, napi, options);\n await runCodeBlockTypecheck(source, options);\n\n const result = napi.transform(source, {\n gfm: options.gfm,\n footnotes: options.footnotes,\n taskLists: options.taskLists,\n tables: options.tables,\n strikethrough: options.strikethrough,\n frontmatter: options.frontmatter,\n tocMaxDepth: options.tocMaxDepth,\n convertMdLinks: ssgOptions?.convertMdLinks,\n baseUrl: ssgOptions?.baseUrl,\n sourcePath: ssgOptions?.sourcePath ?? filePath,\n codeAnnotations: options.codeAnnotations?.enabled ?? false,\n codeAnnotationMetaKey: options.codeAnnotations?.metaKey ?? \"annotate\",\n codeAnnotationSyntax: options.codeAnnotations?.notation ?? \"attribute\",\n codeAnnotationDefaultLineNumbers: options.codeAnnotations?.defaultLineNumbers ?? false,\n wikiLinks: options.wikiLinks?.enabled\n ? {\n enabled: true,\n baseUrl: options.wikiLinks.baseUrl,\n }\n : undefined,\n emojiShortcodes: options.emojiShortcodes?.enabled\n ? {\n enabled: true,\n custom: options.emojiShortcodes.custom,\n }\n : undefined,\n attributes: options.attrs?.enabled ? { enabled: true } : undefined,\n cjkEmphasis: options.cjkEmphasis ?? false,\n codeImports: options.codeImports?.enabled\n ? {\n enabled: true,\n rootDir: options.codeImports.rootDir,\n }\n : undefined,\n // Sanitize once at the end of the JS pipeline so opt-in embeds can be\n // expanded before the allow-list is applied.\n sanitize: undefined,\n editThisPage: options.editThisPage?.enabled\n ? {\n enabled: true,\n repoUrl: options.editThisPage.repoUrl,\n branch: options.editThisPage.branch,\n rootDir: options.editThisPage.rootDir,\n label: options.editThisPage.label,\n }\n : undefined,\n });\n\n if (result.errors.length > 0) {\n console.warn(\"[ox-content] Transform warnings:\", result.errors);\n }\n\n let html = result.html;\n const frontmatter = parseFrontmatterJson(result.frontmatter);\n\n const toc = options.toc ? result.toc.map(normalizeTocEntry) : [];\n\n // Transform mermaid diagrams before highlighting to avoid entity re-encoding\n if (options.mermaid) {\n html = await transformMermaidStatic(html);\n }\n\n // Protect mermaid SVGs from rehype processing (which corrupts <br /> in foreignObjects)\n const { html: protectedHtml, svgs } = protectMermaidSvgs(html);\n html = protectedHtml;\n\n // Apply syntax highlighting if enabled\n if (options.highlight) {\n const originalHtml = html;\n const highlightedHtml = await highlightCode(\n html,\n options.highlightTheme,\n options.highlightLangs,\n );\n html = napi.mergeHighlightedCodeBlocks(originalHtml, highlightedHtml);\n }\n\n // Render static built-in embeds while Mermaid SVG placeholders are protected.\n html = await transformBuiltinEmbeds(\n html,\n options.embeds ?? {\n github: {},\n openGraph: {},\n },\n );\n\n // Restore protected SVGs\n html = restoreMermaidSvgs(html, svgs);\n\n if (options.sanitize?.enabled) {\n html = napi.sanitizeHtml(html, toJsSanitizeOptions(options.sanitize));\n }\n\n // Generate JavaScript module code\n const code = generateModuleCode(html, frontmatter, toc, filePath, options);\n\n return {\n code,\n html,\n frontmatter,\n toc,\n };\n}\n\nasync function runCodeBlockTypecheck(source: string, options: ResolvedOptions): Promise<void> {\n const typecheck = options.codeBlockTypecheck;\n if (!typecheck?.enabled || !source.includes(\"```\")) {\n return;\n }\n\n const diagnostics = await typecheckCodeBlocks(source, {\n languages: typecheck.languages,\n requireMeta: typecheck.requireMeta,\n tsgoCommand: typecheck.tsgoCommand,\n });\n if (diagnostics.length === 0) {\n return;\n }\n\n const message = diagnostics\n .slice(0, 3)\n .map((diagnostic) => `${diagnostic.ruleId} at ${diagnostic.line}: ${diagnostic.message}`)\n .join(\"\\n\");\n if (typecheck.mode === \"error\") {\n throw new Error(`[ox-content] Code block type-checking failed:\\n${message}`);\n }\n console.warn(`[ox-content] Code block type-checking warnings:\\n${message}`);\n}\n\nfunction runCodeBlockLint(source: string, napi: NapiBindings, options: ResolvedOptions): void {\n const lint = options.codeBlockLint;\n if (!lint?.enabled || !source.includes(\"```\")) {\n return;\n }\n\n const diagnostics = napi.lintCodeBlocks(source, {\n enabled: true,\n languages: lint.languages,\n requireLanguage: lint.requireLanguage,\n trailingSpaces: lint.trailingSpaces,\n });\n if (diagnostics.length === 0) {\n return;\n }\n\n const message = diagnostics\n .slice(0, 5)\n .map((diagnostic) => {\n return `${diagnostic.ruleId} at ${diagnostic.line}:${diagnostic.column} ${diagnostic.message}`;\n })\n .join(\"\\n\");\n if (lint.mode === \"error\") {\n throw new Error(`[ox-content] Code block lint failed:\\n${message}`);\n }\n console.warn(`[ox-content] Code block lint warnings:\\n${message}`);\n}\n\nfunction toJsSanitizeOptions(options: ResolvedOptions[\"sanitize\"]): JsSanitizeOptions {\n return {\n enabled: true,\n allowedTags: options.allowedTags,\n allowedAttributes: options.allowedAttributes,\n allowedUrlSchemes: options.allowedUrlSchemes,\n };\n}\n\nfunction parseFrontmatterJson(json: string): Record<string, unknown> {\n if (!json) {\n return {};\n }\n\n try {\n const value = JSON.parse(json);\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n\nfunction normalizeTocEntry(entry: {\n depth: number;\n text: string;\n slug: string;\n children?: TocEntry[];\n}): TocEntry {\n return {\n depth: entry.depth,\n text: entry.text,\n slug: entry.slug,\n children: (entry.children ?? []).map(normalizeTocEntry),\n };\n}\n\n/**\n * Generates the JavaScript module code.\n */\nfunction generateModuleCode(\n html: string,\n frontmatter: Record<string, unknown>,\n toc: TocEntry[],\n filePath: string,\n _options: ResolvedOptions,\n): string {\n const htmlJson = JSON.stringify(html);\n const frontmatterJson = JSON.stringify(frontmatter);\n const tocJson = JSON.stringify(toc);\n\n return `\n// Generated by @ox-content/vite-plugin\n// Source: ${filePath}\n\n/**\n * Rendered HTML content.\n */\nexport const html = ${htmlJson};\n\n/**\n * Parsed frontmatter.\n */\nexport const frontmatter = ${frontmatterJson};\n\n/**\n * Table of contents.\n */\nexport const toc = ${tocJson};\n\n/**\n * Default export with all data.\n */\nexport default {\n html,\n frontmatter,\n toc,\n};\n\n// HMR support\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (newModule) {\n // Trigger re-render with new content\n import.meta.hot.invalidate();\n }\n });\n}\n`;\n}\n\n/**\n * Extracts imports from Markdown content.\n *\n * Supports importing components for interactive islands.\n */\nexport function extractImports(content: string): string[] {\n const importRegex = /^import\\s+.+\\s+from\\s+['\"](.+)['\"]/gm;\n const imports: string[] = [];\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n return imports;\n}\n\n/**\n * Generates an OG image SVG using the Rust-based generator.\n *\n * This function uses the Rust NAPI bindings to generate SVG-based\n * OG images for social media previews. The SVG can be served directly\n * or converted to PNG/JPEG for broader compatibility.\n *\n * In the future, custom JS templates can be provided to override\n * the default Rust-based template.\n *\n * @param data - OG image data (title, description, etc.)\n * @param config - Optional OG image configuration\n * @returns SVG string or null if NAPI bindings are unavailable\n */\nexport async function generateOgImageSvg(\n data: OgImageData,\n config?: OgImageConfig,\n): Promise<string | null> {\n const napi = await loadNapiBindings();\n if (!napi) {\n return null;\n }\n\n // Convert config to NAPI format (camelCase to snake_case)\n const napiConfig = config\n ? {\n width: config.width,\n height: config.height,\n backgroundColor: config.backgroundColor,\n textColor: config.textColor,\n titleFontSize: config.titleFontSize,\n descriptionFontSize: config.descriptionFontSize,\n }\n : undefined;\n\n return napi.generateOgImageSvg(data, napiConfig);\n}\n","/**\n * Source Documentation Extraction and Generation\n *\n * This module provides comprehensive tools for extracting JSDoc/TSDoc comments\n * from TypeScript/JavaScript source files and automatically generating Markdown\n * documentation.\n *\n * ## Features\n *\n * - **Automatic Extraction**: Parses JSDoc comments from functions, classes, interfaces, and types\n * - **Flexible Filtering**: Include/exclude patterns for selective documentation\n * - **Markdown Generation**: Converts extracted docs to organized Markdown files\n * - **Navigation Generation**: Auto-generates sidebar navigation metadata\n * - **GitHub Links**: Includes clickable links to source code on GitHub\n *\n * ## Supported JSDoc Tags\n *\n * - `@param {type} name - description` - Function parameter documentation\n * - `@returns {type} description` - Return value documentation\n * - `@example` - Code examples (multi-line blocks)\n * - `@private` - Mark item as private (excluded from docs if private=false)\n * - `@default value` - Default parameter value\n * - Custom tags are preserved in the `tags` field\n *\n * ## Usage Flow\n *\n * 1. Call `extractDocs()` to parse source files\n * 2. Call `generateMarkdown()` to create Markdown content\n * 3. Call `writeDocs()` to write files to output directory\n * 4. Generated nav.ts can be imported for sidebar navigation\n *\n * @example\n * ```typescript\n * import { extractDocs, generateMarkdown, writeDocs } from './docs';\n *\n * const docsOptions = {\n * enabled: true,\n * src: ['./src'],\n * out: './docs/api',\n * include: ['**\\/*.ts'],\n * exclude: ['**\\/*.test.ts'],\n * groupBy: 'file',\n * githubUrl: 'https://github.com/user/project',\n * };\n *\n * const extracted = await extractDocs(['./src'], docsOptions);\n * const markdown = generateMarkdown(extracted, docsOptions);\n * await writeDocs(markdown, './docs/api', extracted, docsOptions);\n * ```\n */\n\nimport type {\n ResolvedDocsOptions,\n ExtractedDocs,\n DocEntry,\n ResolvedDocsEntryPoint,\n DocsOptions,\n} from \"./types\";\nimport { importNapiModule, importNapiModuleSync } from \"./napi\";\n\nconst DEFAULT_DOCS_INCLUDE = [\n \"**/*.ts\",\n \"**/*.tsx\",\n \"**/*.js\",\n \"**/*.jsx\",\n \"**/*.mts\",\n \"**/*.mjs\",\n \"**/*.cts\",\n \"**/*.cjs\",\n];\n\n/**\n * Extracts JSDoc documentation from source files in specified directories.\n *\n * This function recursively searches directories for source files matching\n * the include/exclude patterns, then extracts all documented items (functions,\n * classes, interfaces, types) from those files.\n *\n * ## Process\n *\n * 1. **File Discovery**: Recursively walks directories, applying filters\n * 2. **File Reading**: Loads each matching file's content\n * 3. **JSDoc Extraction**: Parses JSDoc comments using the native parser\n * 4. **Declaration Matching**: Pairs JSDoc comments with source declarations\n * 5. **Result Collection**: Aggregates extracted documentation by file\n *\n * ## Include/Exclude Patterns\n *\n * Patterns support:\n * - `**` - Match any directory structure\n * - `*` - Match any filename\n * - Standard glob patterns (e.g., `**\\/*.test.ts`)\n *\n * ## Performance Considerations\n *\n * - Uses filesystem I/O which can be slow for large codebases\n * - Consider using more specific include patterns to reduce file scanning\n * - Results are not cached; call once per build/dev session\n *\n * @param srcDirs - Array of source directory paths to scan\n * @param options - Documentation extraction options (filters, grouping, etc.)\n *\n * @returns Promise resolving to array of extracted documentation by file.\n * Each ExtractedDocs object contains file path and array of DocEntry items.\n *\n * @example\n * ```typescript\n * const docs = await extractDocs(\n * ['./packages/vite-plugin/src'],\n * {\n * enabled: true,\n * src: [],\n * out: 'docs',\n * include: ['**\\/*.ts'],\n * exclude: ['**\\/*.test.ts', '**\\/*.spec.ts'],\n * format: 'markdown',\n * private: false,\n * toc: true,\n * groupBy: 'file',\n * generateNav: true,\n * }\n * );\n *\n * // Returns:\n * // [\n * // {\n * // file: '/path/to/transform.ts',\n * // entries: [\n * // { name: 'transformMarkdown', kind: 'function', ... },\n * // { name: 'loadNapiBindings', kind: 'function', ... },\n * // ]\n * // },\n * // ...\n * // ]\n * ```\n */\nexport async function extractDocs(\n srcDirs: string[],\n options: ResolvedDocsOptions,\n): Promise<ExtractedDocs[]> {\n const napi = await importNapiModule();\n\n if (options.entryPoints?.length) {\n const extractDocsFromEntryPoints = (\n napi as {\n extractDocsFromEntryPoints?: (\n entryPoints: ResolvedDocsEntryPoint[],\n options?: { root?: string; private?: boolean; internal?: boolean },\n ) => Array<{ file: string; entries: DocEntry[] }>;\n }\n ).extractDocsFromEntryPoints;\n\n if (!extractDocsFromEntryPoints) {\n throw new Error(\n \"[ox-content] extractDocsFromEntryPoints is not available from @ox-content/napi.\",\n );\n }\n\n return extractDocsFromEntryPoints(options.entryPoints, {\n root: process.cwd(),\n private: options.private,\n internal: options.internal,\n }).map((doc) => ({ file: doc.file, entries: doc.entries }));\n }\n\n const extractDocsFromDirectories = (\n napi as {\n extractDocsFromDirectories?: (\n srcDirs: string[],\n include: string[],\n exclude: string[],\n includePrivate?: boolean,\n includeInternal?: boolean,\n ) => Array<{ file: string; entries: DocEntry[] }>;\n }\n ).extractDocsFromDirectories;\n\n if (!extractDocsFromDirectories) {\n throw new Error(\n \"[ox-content] extractDocsFromDirectories is not available from @ox-content/napi.\",\n );\n }\n\n return extractDocsFromDirectories(\n srcDirs,\n options.include,\n options.exclude,\n options.private,\n options.internal,\n ).map((doc) => ({ file: doc.file, entries: doc.entries }));\n}\n\n/**\n * Generates Markdown documentation from extracted docs.\n */\nexport function generateMarkdown(\n docs: ExtractedDocs[],\n options: ResolvedDocsOptions,\n): Record<string, string> {\n const napi = importNapiModuleSync();\n\n if (typeof napi.generateDocsMarkdown !== \"function\") {\n throw new Error(\n \"[ox-content] generateDocsMarkdown is not available from @ox-content/napi. Please rebuild the NAPI package.\",\n );\n }\n\n return napi.generateDocsMarkdown(toRustDocsModules(docs), {\n groupBy: options.groupBy,\n githubUrl: options.githubUrl,\n linkStyle: options.linkStyle,\n basePath: options.basePath,\n pathStrategy: options.pathStrategy,\n renderStyle: options.renderStyle,\n });\n}\n\n/**\n * Writes generated documentation to the output directory.\n */\nexport async function writeDocs(\n docs: Record<string, string>,\n outDir: string,\n extractedDocs?: ExtractedDocs[],\n options?: ResolvedDocsOptions,\n): Promise<void> {\n const napi = importNapiModuleSync();\n\n if (typeof napi.writeGeneratedDocs !== \"function\") {\n throw new Error(\n \"[ox-content] writeGeneratedDocs is not available from @ox-content/napi. Please rebuild the NAPI package.\",\n );\n }\n\n napi.writeGeneratedDocs(\n docs,\n outDir,\n extractedDocs ? toRustDocsModules(extractedDocs) : undefined,\n {\n generateNav: options?.generateNav ?? false,\n groupBy: options?.groupBy ?? \"file\",\n generatedAt: new Date().toISOString(),\n basePath: options?.basePath,\n pathStrategy: options?.pathStrategy,\n },\n );\n}\n\nexport function toRustDocsModules(docs: ExtractedDocs[]) {\n return docs.map((doc) => ({\n file: doc.file,\n entries: doc.entries.map((entry) => ({\n name: entry.name,\n kind: entry.kind,\n description: entry.description,\n params: entry.params,\n returns: entry.returns,\n examples: entry.examples,\n tags: entry.tags\n ? Object.entries(entry.tags).map(([tag, value]) => ({ tag, value }))\n : undefined,\n private: entry.private ?? false,\n file: entry.file,\n line: entry.line,\n endLine: entry.endLine,\n signature: entry.signature,\n members: entry.members,\n })),\n }));\n}\n\n/**\n * Resolves docs options with defaults.\n */\nexport function resolveDocsOptions(options: false): false;\nexport function resolveDocsOptions(options?: DocsOptions): ResolvedDocsOptions;\nexport function resolveDocsOptions(\n options: DocsOptions | false | undefined,\n): ResolvedDocsOptions | false;\nexport function resolveDocsOptions(\n options: DocsOptions | false | undefined,\n): ResolvedDocsOptions | false {\n if (options === false) {\n return false;\n }\n\n const opts = options || {};\n\n return {\n enabled: opts.enabled ?? true,\n src: opts.src ?? [\"./src\"],\n out: opts.out ?? \"docs/api\",\n include: opts.include ?? DEFAULT_DOCS_INCLUDE,\n exclude: opts.exclude ?? [\"**/*.test.*\", \"**/*.spec.*\", \"node_modules\"],\n entryPoints: opts.entryPoints?.map((entryPoint) =>\n typeof entryPoint === \"string\" ? { path: entryPoint } : entryPoint,\n ),\n format: opts.format ?? \"markdown\",\n private: opts.private ?? false,\n internal: opts.internal ?? false,\n toc: false,\n groupBy: opts.groupBy ?? \"file\",\n githubUrl: opts.githubUrl,\n linkStyle: opts.linkStyle ?? \"markdown\",\n basePath: opts.basePath,\n pathStrategy: opts.pathStrategy ?? \"flat\",\n renderStyle: opts.renderStyle ?? \"html\",\n generateNav: opts.generateNav ?? true,\n };\n}\n","/**\n * HTML → PNG renderer using Chromium screenshots via Playwright.\n */\n\nimport * as path from \"path\";\nimport type { Page } from \"playwright\";\n\n/**\n * Wraps template HTML in a minimal document with viewport locked to given dimensions.\n */\nfunction wrapHtml(bodyHtml: string, width: number, height: number, useBaseUrl: boolean): string {\n const baseTag = useBaseUrl ? `\\n<base href=\"http://localhost/\">` : \"\";\n return `<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"UTF-8\">${baseTag}\n<style>\n* { margin: 0; padding: 0; box-sizing: border-box; }\nhtml, body { width: ${width}px; height: ${height}px; overflow: hidden; }\n</style>\n</head>\n<body>${bodyHtml}</body>\n</html>`;\n}\n\n/**\n * Renders an HTML string to a PNG buffer using Chromium.\n *\n * @param page - Playwright page instance\n * @param html - HTML string from template function\n * @param width - Image width\n * @param height - Image height\n * @param publicDir - Optional public directory for serving local assets (images, fonts, etc.)\n * @returns PNG buffer\n */\nexport async function renderHtmlToPng(\n page: Page,\n html: string,\n width: number,\n height: number,\n publicDir?: string,\n): Promise<Buffer> {\n await page.setViewportSize({ width, height });\n\n // Serve local assets from the public directory\n if (publicDir) {\n const fs = await import(\"fs/promises\");\n await page.route(\"**/*\", async (route) => {\n const url = new URL(route.request().url());\n // Only intercept paths that look like local assets (not data: or blob:)\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n await route.continue();\n return;\n }\n const filePath = path.join(publicDir, url.pathname);\n try {\n const body = await fs.readFile(filePath);\n const ext = path.extname(filePath).toLowerCase();\n const mimeTypes: Record<string, string> = {\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n };\n await route.fulfill({\n body,\n contentType: mimeTypes[ext] || \"application/octet-stream\",\n });\n } catch {\n await route.continue();\n }\n });\n }\n\n const fullHtml = wrapHtml(html, width, height, !!publicDir);\n await page.setContent(fullHtml, { waitUntil: \"networkidle\" });\n\n const screenshot = await page.screenshot({\n type: \"png\",\n clip: { x: 0, y: 0, width, height },\n });\n\n return Buffer.from(screenshot);\n}\n","/**\n * Chromium browser session with automatic cleanup via Explicit Resource Management.\n *\n * Usage:\n * await using session = await openBrowser();\n * const png = await session.renderPage(html, 1200, 630);\n * // browser.close() is called automatically when session goes out of scope\n */\n\nimport type { Page } from \"playwright\";\nimport { renderHtmlToPng } from \"./renderer\";\n\nconst PLAYWRIGHT_BROWSER_INSTALL_HINT =\n \"Install Playwright browsers with `npx playwright install chromium` to enable OG image generation.\";\n\nlet chromiumUnavailableWarned = false;\n\n/**\n * A browser session that can render HTML pages to PNG.\n * Implements AsyncDisposable for automatic cleanup via `await using`.\n */\nexport interface OgBrowserSession extends AsyncDisposable {\n renderPage(html: string, width: number, height: number, publicDir?: string): Promise<Buffer>;\n}\n\n/**\n * Opens a Chromium browser and returns a session for rendering OG images.\n * Returns null if Playwright/Chromium is not available.\n *\n * The session implements AsyncDisposable — use `await using` for automatic cleanup:\n * ```ts\n * await using session = await openBrowser();\n * if (!session) return;\n * const png = await session.renderPage(html, 1200, 630);\n * ```\n */\nexport async function openBrowser(): Promise<OgBrowserSession | null> {\n try {\n const { chromium } = await import(\"playwright\");\n const browser = await chromium.launch({\n headless: true,\n args: [\n \"--no-sandbox\",\n \"--disable-setuid-sandbox\",\n \"--disable-dev-shm-usage\",\n \"--disable-gpu\",\n ],\n });\n\n return {\n async renderPage(\n html: string,\n width: number,\n height: number,\n publicDir?: string,\n ): Promise<Buffer> {\n const page: Page = await browser.newPage();\n try {\n return await renderHtmlToPng(page, html, width, height, publicDir);\n } finally {\n await page.close();\n }\n },\n\n async [Symbol.asyncDispose]() {\n try {\n await browser.close();\n } catch {\n // Ignore close errors\n }\n },\n };\n } catch (err) {\n warnChromiumUnavailableOnce(err);\n return null;\n }\n}\n\nfunction warnChromiumUnavailableOnce(err: unknown): void {\n if (chromiumUnavailableWarned) {\n return;\n }\n\n chromiumUnavailableWarned = true;\n console.warn(\n `[ox-content:og-image] Chromium not available, skipping OG image generation. ${formatChromiumUnavailableDetail(\n err,\n )}`,\n );\n}\n\nfunction formatChromiumUnavailableDetail(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err);\n\n if (\n message.includes(\"Executable doesn't exist\") ||\n message.includes(\"Please run the following command to download new browsers\")\n ) {\n return PLAYWRIGHT_BROWSER_INSTALL_HINT;\n }\n\n return (\n message\n .split(/\\r?\\n/)\n .find((line) => line.trim())\n ?.trim() ?? \"Unknown launch error.\"\n );\n}\n","/**\n * Default OG image template.\n *\n * Uses inline HTML/CSS for a flat, low-color brand card with title,\n * description, siteName, and tags. No external dependencies required.\n */\n\nimport type { OgImageTemplateFn, OgImageTemplateProps } from \"./types\";\n\n/**\n * Escapes HTML special characters.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction normalizeBrandValue(str: string): string {\n return str.replace(/\\s+/g, \"\").toLowerCase();\n}\n\nfunction renderWordmarkSvg(): string {\n return `<svg width=\"430\" height=\"102\" viewBox=\"0 0 270 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"ogWordmarkGradient\" x1=\"286\" y1=\"10\" x2=\"320\" y2=\"54\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"#355cff\"/>\n <stop offset=\"100%\" stop-color=\"#74c7ff\"/>\n </linearGradient>\n </defs>\n <text\n x=\"2\"\n y=\"43\"\n fill=\"#eff6ff\"\n font-family=\"IBM Plex Sans, IBM Plex Mono, Avenir Next, Segoe UI, sans-serif\"\n font-size=\"34\"\n font-weight=\"700\"\n letter-spacing=\"-1.4\"\n >\n OXCONTENT\n </text>\n <text\n x=\"213\"\n y=\"43.5\"\n fill=\"#eff6ff\"\n font-family=\"IBM Plex Sans, IBM Plex Mono, Avenir Next, Segoe UI, sans-serif\"\n font-size=\"40\"\n font-weight=\"400\"\n >\n (\n </text>\n <g transform=\"translate(216 9) scale(0.089) rotate(-7 256 256)\">\n <path\n d=\"M161 96H286C298 96 309 101 318 110L352 144C361 153 366 164 366 176V386C366 399 355 410 342 410H161C148 410 138 399 138 386V120C138 107 148 96 161 96Z\"\n fill=\"url(#ogWordmarkGradient)\"\n />\n </g>\n <text\n x=\"252\"\n y=\"43.5\"\n fill=\"#eff6ff\"\n font-family=\"IBM Plex Sans, IBM Plex Mono, Avenir Next, Segoe UI, sans-serif\"\n font-size=\"40\"\n font-weight=\"400\"\n >\n )\n </text>\n</svg>`;\n}\n\n/**\n * Returns the built-in default template function.\n */\nexport function getDefaultTemplate(): OgImageTemplateFn {\n return function defaultTemplate(props: OgImageTemplateProps): string {\n const { title, description, siteName } = props;\n const rawBrand = siteName?.trim() ? siteName : \"Ox Content\";\n const isBrandCard = normalizeBrandValue(title) === normalizeBrandValue(rawBrand);\n\n const heroTitle = isBrandCard ? \"cargo doc for JavaScript\" : title;\n const heroDescription = isBrandCard\n ? \"Rust-powered docs and high-performance Markdown tooling.\"\n : description && description.trim().length > 0\n ? description\n : \"Rust-powered docs and Markdown tooling.\";\n const descriptionHtml =\n heroDescription.trim().length > 0\n ? `<p style=\"max-width:760px;font-size:28px;color:#93a4c3;line-height:1.45;margin:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;\">${escapeHtml(heroDescription)}</p>`\n : \"\";\n\n return `<div style=\"width:100%;height:100%;position:relative;overflow:hidden;box-sizing:border-box;padding:56px 64px 52px;background:#0b1220;font-family:'IBM Plex Sans','Avenir Next','Segoe UI',system-ui,sans-serif;color:#eff6ff;border:1px solid #223252;border-top:4px solid #4f6fae;\">\n <div style=\"position:relative;z-index:1;display:flex;flex-direction:column;height:100%;\">\n <div style=\"display:flex;align-items:flex-start;\">${renderWordmarkSvg()}</div>\n <div style=\"display:flex;flex-direction:column;justify-content:center;gap:24px;max-width:860px;flex:1;padding:22px 0 0;\">\n <h1 style=\"font-size:78px;font-weight:700;color:#eff6ff;line-height:1.02;letter-spacing:-0.055em;margin:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;\">${escapeHtml(heroTitle)}</h1>\n ${descriptionHtml}\n </div>\n </div>\n</div>`;\n };\n}\n","/**\n * Content-hash based caching for OG images.\n *\n * Uses SHA256 of (template source + props + options) to determine\n * if a re-render is needed. Cache dir: .cache/og-images\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\n\n/**\n * Computes a cache key from template + props + options.\n */\nexport function computeCacheKey(\n templateSource: string,\n props: Record<string, unknown>,\n width: number,\n height: number,\n): string {\n const data = JSON.stringify({ templateSource, props, width, height });\n return crypto.createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\n/**\n * Checks if a cached PNG exists for the given key.\n * Returns the cached file path if found, null otherwise.\n */\nexport async function getCached(cacheDir: string, key: string): Promise<Buffer | null> {\n const filePath = path.join(cacheDir, `${key}.png`);\n try {\n return await fs.readFile(filePath);\n } catch {\n return null;\n }\n}\n\n/**\n * Writes a PNG buffer to the cache.\n */\nexport async function writeCache(cacheDir: string, key: string, png: Buffer): Promise<void> {\n await fs.mkdir(cacheDir, { recursive: true });\n const filePath = path.join(cacheDir, `${key}.png`);\n await fs.writeFile(filePath, png);\n}\n","/**\n * Public API for Chromium-based OG image generation.\n *\n * Orchestrates browser lifecycle, template resolution, caching,\n * and batch rendering with concurrency control.\n */\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\nimport { openBrowser } from \"./browser\";\nimport type { OgBrowserSession } from \"./browser\";\nimport { getDefaultTemplate } from \"./template\";\nimport { computeCacheKey, getCached, writeCache } from \"./cache\";\nimport type {\n OgImageOptions,\n ResolvedOgImageOptions,\n OgImageTemplateProps,\n OgImageTemplateFn,\n} from \"./types\";\n\nexport type {\n OgImageOptions,\n ResolvedOgImageOptions,\n OgImageTemplateProps,\n OgImageTemplateFn,\n} from \"./types\";\n\nexport type { OgBrowserSession } from \"./browser\";\n\n/**\n * Resolves user-provided OG image options with defaults.\n */\nexport function resolveOgImageOptions(options: OgImageOptions | undefined): ResolvedOgImageOptions {\n return {\n template: options?.template,\n vuePlugin: options?.vuePlugin ?? \"vitejs\",\n width: options?.width ?? 1200,\n height: options?.height ?? 630,\n cache: options?.cache ?? true,\n concurrency: options?.concurrency ?? 1,\n };\n}\n\n/**\n * A single page entry for batch OG image generation.\n */\nexport interface OgImagePageEntry {\n /** Props to pass to the template */\n props: OgImageTemplateProps;\n /** Absolute path to write the output PNG */\n outputPath: string;\n}\n\n/**\n * Result of OG image generation for a single page.\n */\nexport interface OgImageResult {\n outputPath: string;\n cached: boolean;\n error?: string;\n}\n\n/**\n * Resolves the template function from options.\n *\n * Dispatches by file extension:\n * - `.vue` → Vue SFC (SSR via vue/server-renderer)\n * - `.svelte` → Svelte SFC (SSR via svelte/server)\n * - `.tsx`/`.jsx` → React Server Component (SSR via react-dom/server)\n * - others → TypeScript template (direct function export)\n */\nasync function resolveTemplate(\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageTemplateFn> {\n if (!options.template) {\n return getDefaultTemplate();\n }\n\n const templatePath = path.resolve(root, options.template);\n\n // Verify file exists\n const fs = await import(\"fs/promises\");\n try {\n await fs.access(templatePath);\n } catch {\n throw new Error(`[ox-content:og-image] Template file not found: ${templatePath}`);\n }\n\n const ext = path.extname(templatePath).toLowerCase();\n\n switch (ext) {\n case \".vue\":\n return resolveVueTemplate(templatePath, options, root);\n case \".svelte\":\n return resolveSvelteTemplate(templatePath, root);\n case \".tsx\":\n case \".jsx\":\n return resolveReactTemplate(templatePath, root);\n default:\n return resolveTsTemplate(templatePath, options, root);\n }\n}\n\n/**\n * Resolves a plain TypeScript template (existing behavior).\n */\nasync function resolveTsTemplate(\n templatePath: string,\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template.mjs\");\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const templateFn = mod.default;\n\n if (typeof templateFn !== \"function\") {\n throw new Error(\n `[ox-content:og-image] Template must default-export a function: ${options.template}`,\n );\n }\n\n return templateFn as OgImageTemplateFn;\n}\n\n/**\n * Resolves a Vue SFC template via SSR.\n *\n * Compiles the SFC with @vue/compiler-sfc (or @vizejs/vite-plugin),\n * bundles with rolldown, then wraps with createSSRApp + renderToString.\n */\nasync function resolveVueTemplate(\n templatePath: string,\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template_vue.mjs\");\n\n const plugins =\n options.vuePlugin === \"vizejs\" ? await getVizejsPlugin() : [createVueCompilerPlugin()];\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n external: [\"vue\", \"vue/server-renderer\"],\n plugins,\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const Component = mod.default;\n\n if (!Component) {\n throw new Error(\n `[ox-content:og-image] Vue template must have a default export: ${templatePath}`,\n );\n }\n\n // Extract CSS from SFC <style> blocks (Vue SSR does not include styles).\n // OG image templates render in complete isolation, so scoping is unnecessary.\n // We use raw CSS content to avoid scope ID mismatches between compilers\n // (e.g., vizejs and @vue/compiler-sfc may produce different scope hashes).\n let extractedCss = ((mod as Record<string, unknown>).__vize_css__ as string) || \"\";\n if (!extractedCss) {\n try {\n let compilerSfc: typeof import(\"@vue/compiler-sfc\");\n try {\n compilerSfc = await import(\"@vue/compiler-sfc\");\n } catch {\n compilerSfc = null as never;\n }\n if (compilerSfc) {\n const sfcSource = await fs.readFile(templatePath, \"utf-8\");\n const { descriptor } = compilerSfc.parse(sfcSource, { filename: templatePath });\n for (const style of descriptor.styles) {\n extractedCss += style.content;\n }\n }\n } catch {\n // CSS extraction is best-effort\n }\n }\n\n // Import Vue SSR utilities\n const { createSSRApp } = await import(\"vue\");\n const { renderToString } = await import(\"vue/server-renderer\");\n\n return async (props) => {\n const app = createSSRApp(Component, props);\n const html = await renderToString(app);\n if (extractedCss) {\n return `<style>${extractedCss}</style>${html}`;\n }\n return html;\n };\n}\n\n/**\n * Creates a rolldown plugin that compiles Vue SFCs using @vue/compiler-sfc.\n */\nfunction createVueCompilerPlugin(): import(\"rolldown\").Plugin {\n return {\n name: \"ox-content-vue-sfc\",\n async transform(code, id) {\n if (!id.endsWith(\".vue\")) return null;\n\n let compilerSfc: typeof import(\"@vue/compiler-sfc\");\n try {\n compilerSfc = await import(\"@vue/compiler-sfc\");\n } catch {\n throw new Error(\n \"[ox-content:og-image] @vue/compiler-sfc is required for .vue templates. \" +\n \"Install it with: pnpm add -D @vue/compiler-sfc\",\n );\n }\n\n const { descriptor } = compilerSfc.parse(code, { filename: id });\n\n // Compile <script setup> or <script>\n let scriptCode: string;\n if (descriptor.scriptSetup || descriptor.script) {\n const compiled = compilerSfc.compileScript(descriptor, {\n id,\n inlineTemplate: true,\n });\n scriptCode = compiled.content;\n } else {\n // Template-only SFC: compile template separately\n if (!descriptor.template) {\n throw new Error(\n `[ox-content:og-image] Vue SFC must have a <template> or <script>: ${id}`,\n );\n }\n const templateResult = compilerSfc.compileTemplate({\n source: descriptor.template.content,\n filename: id,\n id,\n });\n if (templateResult.errors.length > 0) {\n throw new Error(\n `[ox-content:og-image] Vue template compilation errors in ${id}: ${templateResult.errors.map(String).join(\", \")}`,\n );\n }\n scriptCode = `${templateResult.code}\\nexport default { render }`;\n }\n\n // Determine if the compiled output contains TypeScript\n const isTs = !!(descriptor.scriptSetup?.lang === \"ts\" || descriptor.script?.lang === \"ts\");\n\n return { code: scriptCode, moduleType: isTs ? \"ts\" : \"js\" };\n },\n };\n}\n\n/**\n * Loads @vizejs/vite-plugin as a rolldown plugin for Vue SFC compilation.\n */\nasync function getVizejsPlugin(): Promise<import(\"rolldown\").Plugin[]> {\n try {\n const vizejs = await import(\"@vizejs/vite-plugin\");\n const plugin = vizejs.default?.() ?? vizejs;\n return Array.isArray(plugin) ? plugin : [plugin];\n } catch {\n throw new Error(\n \"[ox-content:og-image] @vizejs/vite-plugin is required when vuePlugin is 'vizejs'. \" +\n \"Install it with: pnpm add -D @vizejs/vite-plugin\",\n );\n }\n}\n\n/**\n * Resolves a Svelte SFC template via SSR.\n *\n * Compiles the SFC with svelte/compiler (server mode + runes),\n * bundles with rolldown, then wraps with svelte/server render().\n */\nasync function resolveSvelteTemplate(\n templatePath: string,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template_svelte.mjs\");\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n external: [\"svelte\", \"svelte/server\", \"svelte/internal\", \"svelte/internal/server\"],\n plugins: [createSvelteCompilerPlugin()],\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const Component = mod.default;\n\n if (!Component) {\n throw new Error(\n `[ox-content:og-image] Svelte template must have a default export: ${templatePath}`,\n );\n }\n\n // Import Svelte SSR utility\n const { render } = (await import(\"svelte/server\")) as {\n render: (component: unknown, options: { props: Record<string, unknown> }) => { body: string };\n };\n\n return async (props) => {\n const { body } = render(Component, { props });\n return body;\n };\n}\n\n/**\n * Creates a rolldown plugin that compiles Svelte SFCs using svelte/compiler.\n */\nfunction createSvelteCompilerPlugin(): import(\"rolldown\").Plugin {\n return {\n name: \"ox-content-svelte-sfc\",\n async transform(code, id) {\n if (!id.endsWith(\".svelte\")) return null;\n\n let svelteCompiler: typeof import(\"svelte/compiler\");\n try {\n svelteCompiler = await import(\"svelte/compiler\");\n } catch {\n throw new Error(\n \"[ox-content:og-image] svelte is required for .svelte templates. \" +\n \"Install it with: pnpm add -D svelte\",\n );\n }\n\n const result = svelteCompiler.compile(code, {\n generate: \"server\",\n runes: true,\n filename: id,\n });\n\n return { code: result.js.code };\n },\n };\n}\n\n/**\n * Resolves a React (.tsx/.jsx) template via SSR.\n *\n * Bundles with rolldown (JSX transform), then wraps with\n * react-dom/server renderToReadableStream for async Server Component support.\n */\nasync function resolveReactTemplate(\n templatePath: string,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template_react.mjs\");\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n external: [\n \"react\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n \"react-dom\",\n \"react-dom/server\",\n ],\n transform: {\n jsx: \"react-jsx\",\n },\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const Component = mod.default;\n\n if (!Component) {\n throw new Error(\n `[ox-content:og-image] React template must have a default export: ${templatePath}`,\n );\n }\n\n // Import React SSR utilities\n let React: typeof import(\"react\");\n let ReactDOMServer: typeof import(\"react-dom/server\");\n try {\n React = await import(\"react\");\n ReactDOMServer = await import(\"react-dom/server\");\n } catch {\n throw new Error(\n \"[ox-content:og-image] react and react-dom are required for .tsx/.jsx templates. \" +\n \"Install them with: pnpm add -D react react-dom\",\n );\n }\n\n return async (props) => {\n const element = React.createElement(Component, props);\n // Use renderToReadableStream for async Server Component support\n const stream = await ReactDOMServer.renderToReadableStream(element);\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n const decoder = new TextDecoder();\n return (\n chunks.map((chunk) => decoder.decode(chunk, { stream: true })).join(\"\") + decoder.decode()\n );\n };\n}\n\n/**\n * Computes a stable template source identifier for cache keys.\n *\n * For custom templates, hashes the file content so cache invalidates\n * when the template changes. For the default template, returns a fixed string.\n */\nasync function computeTemplateSource(\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<string> {\n if (!options.template) {\n return \"__default__\";\n }\n\n const fs = await import(\"fs/promises\");\n const templatePath = path.resolve(root, options.template);\n const content = await fs.readFile(templatePath, \"utf-8\");\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n/**\n * Generates OG images for a batch of pages.\n *\n * Manages the full lifecycle: resolve template → launch browser (with `using`) →\n * render each page (with caching and concurrency).\n *\n * All errors are non-fatal: failures are reported in results but never throw.\n */\nexport async function generateOgImages(\n pages: OgImagePageEntry[],\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageResult[]> {\n if (pages.length === 0) return [];\n\n // Resolve template\n const templateFn = await resolveTemplate(options, root);\n\n // Compute template source for cache key\n const templateSource = await computeTemplateSource(options, root);\n\n // Cache directory\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n\n // Try to serve all from cache first if caching is enabled\n if (options.cache) {\n const allCached = await tryServeAllFromCache(pages, templateSource, options, cacheDir);\n if (allCached) return allCached;\n }\n\n // Launch browser\n await using session = await openBrowser();\n if (!session) {\n return pages.map((p) => ({\n outputPath: p.outputPath,\n cached: false,\n error: \"Chromium not available\",\n }));\n }\n\n const results: OgImageResult[] = [];\n\n // Resolve public directory for serving local assets in templates\n const publicDir = path.join(root, \"public\");\n\n // Process pages with concurrency control\n const concurrency = Math.max(1, options.concurrency);\n\n for (let i = 0; i < pages.length; i += concurrency) {\n const batch = pages.slice(i, i + concurrency);\n const batchResults = await Promise.all(\n batch.map((entry) =>\n renderSinglePage(entry, templateFn, templateSource, options, cacheDir, session, publicDir),\n ),\n );\n results.push(...batchResults);\n }\n\n return results;\n}\n\n/**\n * Tries to serve all pages from cache.\n * Returns results if ALL pages are cached, null otherwise.\n */\nasync function tryServeAllFromCache(\n pages: OgImagePageEntry[],\n templateSource: string,\n options: ResolvedOgImageOptions,\n cacheDir: string,\n): Promise<OgImageResult[] | null> {\n const fs = await import(\"fs/promises\");\n const results: OgImageResult[] = [];\n\n for (const entry of pages) {\n const key = computeCacheKey(\n templateSource,\n entry.props as unknown as Record<string, unknown>,\n options.width,\n options.height,\n );\n const cached = await getCached(cacheDir, key);\n if (!cached) return null; // At least one miss, need browser\n\n // Write cached file to output\n await fs.mkdir(path.dirname(entry.outputPath), { recursive: true });\n await fs.writeFile(entry.outputPath, cached);\n results.push({ outputPath: entry.outputPath, cached: true });\n }\n\n return results;\n}\n\n/**\n * Renders a single page to PNG, with cache support.\n */\nasync function renderSinglePage(\n entry: OgImagePageEntry,\n templateFn: OgImageTemplateFn,\n templateSource: string,\n options: ResolvedOgImageOptions,\n cacheDir: string,\n session: OgBrowserSession,\n publicDir?: string,\n): Promise<OgImageResult> {\n const fs = await import(\"fs/promises\");\n\n try {\n // Check cache\n if (options.cache) {\n const key = computeCacheKey(\n templateSource,\n entry.props as unknown as Record<string, unknown>,\n options.width,\n options.height,\n );\n const cached = await getCached(cacheDir, key);\n if (cached) {\n await fs.mkdir(path.dirname(entry.outputPath), { recursive: true });\n await fs.writeFile(entry.outputPath, cached);\n return { outputPath: entry.outputPath, cached: true };\n }\n }\n\n // Render template to HTML (may be async for SFC templates)\n const html = await templateFn(entry.props);\n\n // Render HTML to PNG via session (page create/close handled internally)\n const png = await session.renderPage(html, options.width, options.height, publicDir);\n\n // Write output\n await fs.mkdir(path.dirname(entry.outputPath), { recursive: true });\n await fs.writeFile(entry.outputPath, png);\n\n // Write cache\n if (options.cache) {\n const key = computeCacheKey(\n templateSource,\n entry.props as unknown as Record<string, unknown>,\n options.width,\n options.height,\n );\n await writeCache(cacheDir, key, png);\n }\n\n return { outputPath: entry.outputPath, cached: false };\n } catch (err) {\n return {\n outputPath: entry.outputPath,\n cached: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * Island Parser\n *\n * Detects <Island> components in HTML and transforms them\n * into hydration-ready elements with data attributes.\n */\n\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeStringify from \"rehype-stringify\";\nimport type { Root, Element } from \"hast\";\n\nexport type LoadStrategy = \"eager\" | \"idle\" | \"visible\" | \"media\";\n\nexport interface IslandInfo {\n component: string;\n load: LoadStrategy;\n mediaQuery?: string;\n props: Record<string, unknown>;\n}\n\nexport interface ParseIslandsResult {\n html: string;\n islands: IslandInfo[];\n}\n\n/**\n * Get element attribute value.\n */\nfunction getAttribute(el: Element, name: string): string | undefined {\n const value = el.properties?.[name];\n if (typeof value === \"string\") return value;\n if (Array.isArray(value)) return value.join(\" \");\n return undefined;\n}\n\n/**\n * Parse JSX-style props from attributes.\n */\nfunction parseProps(el: Element): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n\n if (!el.properties) return props;\n\n for (const [key, value] of Object.entries(el.properties)) {\n // Skip special attributes\n if ([\"load\", \"media\", \"className\", \"class\"].includes(key)) continue;\n\n // Handle JSX-style props like {0} or {true}\n if (typeof value === \"string\") {\n // Try to parse as JSON/JS value if it looks like one\n const trimmed = value.trim();\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n const inner = trimmed.slice(1, -1);\n try {\n // Try JSON parse first\n props[key] = JSON.parse(inner);\n } catch {\n // Try evaluating simple expressions\n if (inner === \"true\") props[key] = true;\n else if (inner === \"false\") props[key] = false;\n else if (inner === \"null\") props[key] = null;\n else if (!Number.isNaN(Number(inner))) props[key] = Number(inner);\n else props[key] = value;\n }\n } else {\n props[key] = value;\n }\n } else if (typeof value === \"number\" || typeof value === \"boolean\") {\n props[key] = value;\n } else if (Array.isArray(value)) {\n props[key] = value;\n }\n }\n\n return props;\n}\n\n/**\n * Find the component element inside <Island>.\n */\nfunction findComponentElement(children: Element[\"children\"]): Element | null {\n for (const child of children) {\n if (child.type === \"element\") {\n // Skip text/whitespace, look for actual component\n if (child.tagName !== \"br\" && child.tagName !== \"span\") {\n return child;\n }\n }\n }\n return null;\n}\n\n/**\n * Get component name from child element.\n */\nfunction getComponentName(el: Element): string {\n // PascalCase tag names are components\n const tagName = el.tagName;\n if (tagName && /^[A-Z]/.test(tagName)) {\n return tagName;\n }\n // Check for data-component attribute\n return getAttribute(el, \"data-component\") || tagName;\n}\n\nlet islandCounter = 0;\n\n/**\n * Reset island counter (for testing).\n */\nexport function resetIslandCounter(): void {\n islandCounter = 0;\n}\n\n/**\n * Rehype plugin to transform Island components.\n */\nfunction rehypeIslands(collectedIslands: IslandInfo[]) {\n return (tree: Root) => {\n const visit = (node: Root | Element) => {\n if (\"children\" in node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n if (child.type === \"element\") {\n // Check for <Island> component\n if (child.tagName.toLowerCase() === \"island\") {\n const load = (getAttribute(child, \"load\") as LoadStrategy) || \"eager\";\n const mediaQuery = getAttribute(child, \"media\");\n\n // Find the component inside\n const componentEl = findComponentElement(child.children);\n\n if (componentEl) {\n const componentName = getComponentName(componentEl);\n const componentProps = parseProps(componentEl);\n\n // Collect island info\n const islandInfo: IslandInfo = {\n component: componentName,\n load,\n mediaQuery,\n props: componentProps,\n };\n collectedIslands.push(islandInfo);\n\n // Create island wrapper with data attributes\n const islandId = `ox-island-${islandCounter++}`;\n\n const islandElement: Element = {\n type: \"element\",\n tagName: \"div\",\n properties: {\n id: islandId,\n \"data-ox-island\": componentName,\n \"data-ox-load\": load,\n ...(mediaQuery && { \"data-ox-media\": mediaQuery }),\n \"data-ox-props\": JSON.stringify(componentProps),\n className: [\"ox-island\"],\n },\n children: [\n // Keep original content as fallback/placeholder\n ...componentEl.children,\n ],\n };\n\n node.children[i] = islandElement;\n }\n } else {\n visit(child);\n }\n }\n }\n }\n };\n\n visit(tree);\n };\n}\n\n/**\n * Transform Island components in HTML.\n *\n * Converts:\n * ```html\n * <Island load=\"visible\">\n * <Counter initial={0} />\n * </Island>\n * ```\n *\n * To:\n * ```html\n * <div id=\"ox-island-0\"\n * data-ox-island=\"Counter\"\n * data-ox-load=\"visible\"\n * data-ox-props='{\"initial\":0}'\n * class=\"ox-island\">\n * <!-- fallback content -->\n * </div>\n * ```\n */\nexport async function transformIslands(html: string): Promise<ParseIslandsResult> {\n const islands: IslandInfo[] = [];\n\n const result = await unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeIslands, islands)\n .use(rehypeStringify)\n .process(html);\n\n return {\n html: String(result),\n islands,\n };\n}\n\n/**\n * Check if HTML contains any Island components.\n */\nexport function hasIslands(html: string): boolean {\n return /<island[\\s>]/i.test(html);\n}\n\n/**\n * Extract island info without transforming HTML.\n * Useful for analysis/bundling purposes.\n */\nexport async function extractIslandInfo(html: string): Promise<IslandInfo[]> {\n const { islands } = await transformIslands(html);\n return islands;\n}\n\n/**\n * Generate client-side hydration script.\n * This is a minimal script that imports and initializes islands.\n */\nexport function generateHydrationScript(components: string[]): string {\n if (components.length === 0) return \"\";\n\n const imports = components.map((name) => `import ${name} from './${name}';`).join(\"\\n\");\n\n return `\nimport { initIslands } from '@ox-content/islands';\n${imports}\n\nconst components = {\n ${components.join(\",\\n \")}\n};\n\n// Initialize with your framework's hydration\n// This example uses Vue, adapt for React/Svelte/etc.\nimport { createApp, h } from 'vue';\n\ninitIslands((el, props) => {\n const name = el.dataset.oxIsland;\n const Component = components[name];\n if (!Component) {\n console.warn(\\`[ox-islands] Unknown component: \\${name}\\`);\n return;\n }\n\n const app = createApp({ render: () => h(Component, props) });\n app.mount(el);\n\n return () => app.unmount();\n});\n`;\n}\n","/**\n * SSG (Static Site Generation) module for ox-content\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { transformMarkdown } from \"./transform\";\nimport { generateOgImages } from \"./og-image\";\nimport type { OgImagePageEntry } from \"./og-image\";\nimport { transformAllPlugins } from \"./plugins\";\nimport type { TransformAllOptions } from \"./plugins\";\nimport { protectMermaidSvgs, restoreMermaidSvgs } from \"./plugins/mermaid-protect\";\nimport { transformIslands, hasIslands } from \"./island\";\nimport { importNapiModule, importNapiModuleSync } from \"./napi\";\nimport { DEFAULT_MARKDOWN_EXTENSIONS } from \"./markdown\";\nimport type {\n ResolvedOptions,\n ResolvedSsgOptions,\n SsgOptions,\n SsgNavigationGroup,\n TocEntry,\n HeroConfig,\n FeatureConfig,\n LocaleConfig,\n} from \"./types\";\nimport { resolveTheme, themeToNapi } from \"./theme\";\nimport type { ResolvedThemeConfig, SidebarItem } from \"./theme\";\nimport { normalizeVitePressFrontmatter } from \"./vitepress\";\n\n/**\n * Navigation item for SSG.\n */\nexport interface SsgNavItem {\n title: string;\n path: string;\n href: string;\n children?: SsgNavItem[];\n collapsed?: boolean;\n}\n\n/**\n * Entry page configuration for SSG (passed to Rust).\n */\nexport interface SsgEntryPageConfig {\n hero?: HeroConfig;\n features?: FeatureConfig[];\n}\n\n/**\n * Page data for SSG.\n */\nexport interface SsgPageData {\n title: string;\n description?: string;\n content: string;\n toc: TocEntry[];\n lastUpdated?: number;\n frontmatter: Record<string, unknown>;\n path: string;\n href: string;\n /** Entry page configuration (if layout: entry) */\n entryPage?: SsgEntryPageConfig;\n}\n\ninterface SsgRoutePaths {\n outputPath: string;\n urlPath: string;\n href: string;\n ogImagePath: string;\n ogImageUrl: string;\n}\n\n/**\n * Deprecated compatibility export for consumers that imported the former\n * TypeScript SSG template. HTML generation is Rust-backed now.\n *\n * @deprecated Use `generateHtmlPage`/`buildSsg` instead.\n */\nexport const DEFAULT_HTML_TEMPLATE = \"<!-- ox-content default HTML template is Rust-backed -->\";\n\n/**\n * Resolves SSG options with defaults.\n */\nexport function resolveSsgOptions(ssg: SsgOptions | boolean | undefined): ResolvedSsgOptions {\n if (ssg === false) {\n return {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n lastUpdated: false,\n };\n }\n\n if (ssg === true || ssg === undefined) {\n return {\n enabled: true,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n lastUpdated: false,\n theme: resolveTheme(undefined),\n };\n }\n\n return {\n enabled: ssg.enabled ?? true,\n extension: ssg.extension ?? \".html\",\n clean: ssg.clean ?? false,\n bare: ssg.bare ?? false,\n siteName: ssg.siteName,\n ogImage: ssg.ogImage,\n generateOgImage: ssg.generateOgImage ?? false,\n lastUpdated: ssg.lastUpdated ?? false,\n siteUrl: ssg.siteUrl,\n theme: resolveTheme(ssg.theme),\n navigation: ssg.navigation,\n };\n}\n\n/**\n * Extracts title from content or frontmatter.\n */\nexport function extractTitle(content: string, frontmatter: Record<string, unknown>): string {\n return importNapiModuleSync().extractSsgTitle(\n content,\n typeof frontmatter.title === \"string\" ? frontmatter.title : undefined,\n );\n}\n\n/**\n * Generates bare HTML page (no navigation, no styles).\n */\nexport function generateBareHtmlPage(content: string, title: string): string {\n return importNapiModuleSync().generateSsgBareHtml(content, title);\n}\n\n/** NAPI-facing nav group shape produced from a [`NavGroup`]. */\ninterface RustNavGroup {\n title: string;\n collapsed?: boolean;\n items: SsgNavItem[];\n}\n\n/**\n * Per-build cache for the Rust-facing nav conversion. `navGroups` is the same\n * `context.navItems` reference for every page in a build, so the deep recursive\n * copy below only needs to run once per build instead of once per page.\n */\nconst navGroupsForRustCache = new WeakMap<NavGroup[], RustNavGroup[]>();\n\nfunction toRustNavItem(item: SsgNavItem): SsgNavItem {\n return {\n title: item.title,\n path: item.path,\n href: item.href,\n children: item.children?.map(toRustNavItem),\n collapsed: item.collapsed,\n };\n}\n\nfunction convertNavGroupsForRust(navGroups: NavGroup[]): RustNavGroup[] {\n const cached = navGroupsForRustCache.get(navGroups);\n if (cached) {\n return cached;\n }\n const converted = navGroups.map((group) => ({\n title: group.title,\n collapsed: group.collapsed,\n items: group.items.map(toRustNavItem),\n }));\n navGroupsForRustCache.set(navGroups, converted);\n return converted;\n}\n\n/**\n * Converts a `TocEntry` tree into the plain shape the Rust binding expects.\n * Hoisted to module scope so it isn't reallocated for every page; the\n * per-page `.map` over `pageData.toc` still runs since the TOC is page-specific.\n */\nfunction toRustTocEntry(entry: TocEntry): TocEntry {\n return {\n depth: entry.depth,\n text: entry.text,\n slug: entry.slug,\n children: entry.children?.map(toRustTocEntry) ?? [],\n };\n}\n\n/** Rust-facing locale shape. */\ninterface RustLocale {\n code: string;\n name: string;\n dir: string;\n}\n\n/**\n * Per-build cache for the Rust-facing locale list. `i18n.locales` is the same\n * reference for every page in a build, so this mapping (and the `?? \"ltr\"`\n * default) only runs once per build instead of once per page.\n */\nconst rustLocalesCache = new WeakMap<LocaleConfig[], RustLocale[]>();\n\nfunction toRustLocales(locales: LocaleConfig[]): RustLocale[] {\n const cached = rustLocalesCache.get(locales);\n if (cached) {\n return cached;\n }\n const converted = locales.map((locale) => ({\n code: locale.code,\n name: locale.name,\n dir: locale.dir ?? \"ltr\",\n }));\n rustLocalesCache.set(locales, converted);\n return converted;\n}\n\n/**\n * Per-build cache for the locale-code list passed to `getSsgPageLocale`. The\n * `i18n.locales` reference is stable across a build, so the `.map` to codes\n * runs once instead of once per page.\n */\nconst localeCodesCache = new WeakMap<LocaleConfig[], string[]>();\n\nfunction localeCodesFor(locales: LocaleConfig[]): string[] {\n const cached = localeCodesCache.get(locales);\n if (cached) {\n return cached;\n }\n const codes = locales.map((locale) => locale.code);\n localeCodesCache.set(locales, codes);\n return codes;\n}\n\n/**\n * Generates HTML page with navigation using Rust NAPI bindings.\n */\nexport async function generateHtmlPage(\n pageData: SsgPageData,\n navGroups: NavGroup[],\n siteName: string,\n base: string,\n ogImage?: string,\n theme?: ResolvedThemeConfig,\n locale?: string,\n availableLocales?: LocaleConfig[],\n): Promise<string> {\n const mod = await importNapiModule();\n\n // Convert TocEntry to the format expected by Rust (converter is module-scoped).\n const tocForRust = pageData.toc.map(toRustTocEntry);\n\n // Convert NavGroup to the format expected by Rust (cached per build).\n const navGroupsForRust = convertNavGroupsForRust(navGroups);\n\n // Convert theme to NAPI format if provided\n const themeForRust = theme ? themeToNapi(theme) : undefined;\n\n // Convert entry page to NAPI format if provided\n const entryPageForRust = pageData.entryPage\n ? {\n hero: pageData.entryPage.hero\n ? {\n name: pageData.entryPage.hero.name,\n text: pageData.entryPage.hero.text,\n tagline: pageData.entryPage.hero.tagline,\n notice: pageData.entryPage.hero.notice\n ? {\n title: pageData.entryPage.hero.notice.title,\n body: pageData.entryPage.hero.notice.body,\n }\n : undefined,\n image: pageData.entryPage.hero.image\n ? {\n src: pageData.entryPage.hero.image.src,\n lightSrc: pageData.entryPage.hero.image.lightSrc,\n darkSrc: pageData.entryPage.hero.image.darkSrc,\n alt: pageData.entryPage.hero.image.alt,\n width: pageData.entryPage.hero.image.width,\n height: pageData.entryPage.hero.image.height,\n }\n : undefined,\n actions: pageData.entryPage.hero.actions?.map((a) => ({\n theme: a.theme,\n text: a.text,\n link: a.link,\n })),\n }\n : undefined,\n features: pageData.entryPage.features?.map((f) => ({\n icon: f.icon,\n title: f.title,\n details: f.details,\n link: f.link,\n linkText: f.linkText,\n })),\n }\n : undefined;\n\n return mod.generateSsgHtml(\n {\n title: pageData.title,\n description: pageData.description,\n content: pageData.content,\n toc: tocForRust,\n lastUpdated: pageData.lastUpdated,\n path: pageData.path,\n entryPage: entryPageForRust,\n },\n navGroupsForRust,\n {\n siteName,\n base,\n ogImage,\n theme: themeForRust,\n locale,\n availableLocales: availableLocales ? toRustLocales(availableLocales) : undefined,\n },\n );\n}\n\ninterface GeneratedHtmlPage {\n inputPath: string;\n outputPath: string;\n html: string;\n}\n\ninterface ExternalizedSharedAsset {\n outputPath: string;\n content: string;\n}\n\nasync function externalizeSharedPageAssets(\n pages: GeneratedHtmlPage[],\n outDir: string,\n base: string,\n): Promise<{ pages: GeneratedHtmlPage[]; assets: string[] }> {\n const mod = await importNapiModule();\n const optimized = mod.externalizeSsgAssets(pages, outDir, base) as {\n pages: GeneratedHtmlPage[];\n assets: ExternalizedSharedAsset[];\n };\n\n await Promise.all(\n optimized.assets.map(async (asset) => {\n await fs.mkdir(path.dirname(asset.outputPath), { recursive: true });\n await fs.writeFile(asset.outputPath, asset.content, \"utf-8\");\n }),\n );\n\n return {\n pages: optimized.pages,\n assets: optimized.assets.map((asset) => asset.outputPath),\n };\n}\n\n/**\n * Converts a markdown file path to its corresponding HTML output path.\n */\nexport function getOutputPath(\n inputPath: string,\n srcDir: string,\n outDir: string,\n extension: string,\n): string {\n return importNapiModuleSync().getSsgOutputPath(inputPath, srcDir, outDir, extension);\n}\n\n/**\n * Converts a markdown file path to a relative URL path.\n */\nexport function getUrlPath(inputPath: string, srcDir: string): string {\n return importNapiModuleSync().getSsgUrlPath(inputPath, srcDir);\n}\n\n/**\n * Converts a markdown file path to an href.\n */\nexport function getHref(\n inputPath: string,\n srcDir: string,\n base: string,\n extension: string,\n): string {\n return importNapiModuleSync().getSsgHref(inputPath, srcDir, base, extension);\n}\n\n/**\n * Resolves manual navigation config to the format used by the built-in SSG renderer.\n */\nexport function resolveNavigationGroups(\n navigation: SsgNavigationGroup[] | undefined,\n base: string,\n extension: string,\n): NavGroup[] | undefined {\n if (!navigation) {\n return undefined;\n }\n\n return importNapiModuleSync().resolveSsgNavigationGroups(navigation, base, extension);\n}\n\nexport function getPageLocale(urlPath: string, i18n: ResolvedOptions[\"i18n\"]): string | undefined {\n if (!i18n) return undefined;\n return (\n importNapiModuleSync().getSsgPageLocale(\n urlPath,\n i18n.defaultLocale,\n localeCodesFor(i18n.locales),\n ) ?? undefined\n );\n}\n\nfunction getRoutePaths(\n inputPath: string,\n srcDir: string,\n outDir: string,\n base: string,\n extension: string,\n siteUrl?: string,\n): SsgRoutePaths {\n return importNapiModuleSync().resolveSsgRoutePaths(\n inputPath,\n srcDir,\n outDir,\n base,\n extension,\n siteUrl,\n );\n}\n\n/**\n * Formats a file/dir name as a title.\n */\nexport function formatTitle(name: string): string {\n return importNapiModuleSync().formatSsgTitle(name);\n}\n\n/**\n * Collects all markdown files from the source directory.\n */\nexport async function collectMarkdownFiles(\n srcDir: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): Promise<string[]> {\n return importNapiModuleSync().collectSsgMarkdownFiles(srcDir, [...extensions]);\n}\n\n/**\n * Navigation group for hierarchical navigation.\n */\nexport interface NavGroup {\n title: string;\n items: SsgNavItem[];\n collapsed?: boolean;\n}\n\n/**\n * Builds navigation items from markdown files, grouped by directory.\n */\nexport function buildNavItems(\n markdownFiles: string[],\n srcDir: string,\n base: string,\n extension: string,\n): NavGroup[] {\n return importNapiModuleSync().buildSsgNavItems(markdownFiles, srcDir, base, extension);\n}\n\n/**\n * Builds navigation items from an explicit theme sidebar tree.\n */\nexport function buildThemeNavItems(\n sidebar: SidebarItem[],\n base: string,\n extension: string,\n): NavGroup[] {\n return importNapiModuleSync().buildSsgThemeNavItems(sidebar, base, extension);\n}\n\ninterface BuildSsgContext {\n options: ResolvedOptions;\n ssgOptions: ResolvedSsgOptions;\n root: string;\n srcDir: string;\n outDir: string;\n base: string;\n siteName: string;\n navItems: NavGroup[];\n shouldGenerateOgImages: boolean;\n napi?: Awaited<ReturnType<typeof importNapiModule>>;\n}\n\ninterface PageProcessResult {\n inputPath: string;\n routePaths: SsgRoutePaths;\n transformedHtml: string;\n title: string;\n description?: string;\n lastUpdated?: number;\n frontmatter: Record<string, unknown>;\n toc: TocEntry[];\n}\n\ninterface CollectedPageResults {\n pageResults: PageProcessResult[];\n ogImageEntries: OgImagePageEntry[];\n ogImageInputPaths: string[];\n ogImageUrlMap: Map<string, string>;\n errors: string[];\n}\n\n/**\n * Builds all markdown files to static HTML.\n */\nexport async function buildSsg(\n options: ResolvedOptions,\n root: string,\n): Promise<{ files: string[]; errors: string[] }> {\n const ssgOptions = options.ssg;\n if (!ssgOptions.enabled) {\n return { files: [], errors: [] };\n }\n\n const srcDir = path.resolve(root, options.srcDir);\n const outDir = path.resolve(root, options.outDir);\n const generatedFiles: string[] = [];\n const errors: string[] = [];\n\n await cleanOutputDirectory(ssgOptions, outDir);\n\n const markdownFiles = await collectMarkdownFiles(srcDir, options.extensions);\n const context = await createBuildSsgContext(options, root, srcDir, outDir, markdownFiles);\n const collected = await collectPageResults(context, markdownFiles);\n errors.push(...collected.errors);\n\n await generateOgImageAssets(context, collected, generatedFiles, errors);\n\n const generatedPages = await generateHtmlPages(context, collected.pageResults, collected, errors);\n await writeGeneratedPages(generatedPages, context, generatedFiles);\n\n return { files: generatedFiles, errors };\n}\n\nasync function cleanOutputDirectory(ssgOptions: ResolvedSsgOptions, outDir: string): Promise<void> {\n if (!ssgOptions.clean) {\n return;\n }\n\n try {\n await fs.rm(outDir, { recursive: true, force: true });\n } catch {\n // Ignore if directory doesn't exist.\n }\n}\n\nasync function createBuildSsgContext(\n options: ResolvedOptions,\n root: string,\n srcDir: string,\n outDir: string,\n markdownFiles: string[],\n): Promise<BuildSsgContext> {\n const ssgOptions = options.ssg;\n const base = options.base.endsWith(\"/\") ? options.base : options.base + \"/\";\n const navItems =\n resolveNavigationGroups(ssgOptions.navigation, base, ssgOptions.extension) ??\n (ssgOptions.theme?.sidebar.length\n ? buildThemeNavItems(ssgOptions.theme.sidebar, base, ssgOptions.extension)\n : buildNavItems(markdownFiles, srcDir, base, ssgOptions.extension));\n\n return {\n options,\n ssgOptions,\n root,\n srcDir,\n outDir,\n base,\n navItems,\n siteName: await resolveSiteName(root, ssgOptions),\n shouldGenerateOgImages: (options.ogImage || ssgOptions.generateOgImage) && !ssgOptions.bare,\n napi: ssgOptions.lastUpdated ? await importNapiModule() : undefined,\n };\n}\n\nasync function resolveSiteName(root: string, ssgOptions: ResolvedSsgOptions): Promise<string> {\n if (ssgOptions.siteName) {\n return ssgOptions.siteName;\n }\n\n try {\n const pkgPath = path.join(root, \"package.json\");\n const pkg = JSON.parse(await fs.readFile(pkgPath, \"utf-8\"));\n return pkg.name ? formatTitle(pkg.name) : \"Documentation\";\n } catch {\n return \"Documentation\";\n }\n}\n\nasync function collectPageResults(\n context: BuildSsgContext,\n markdownFiles: string[],\n): Promise<CollectedPageResults> {\n const collected: CollectedPageResults = {\n pageResults: [],\n ogImageEntries: [],\n ogImageInputPaths: [],\n ogImageUrlMap: new Map(),\n errors: [],\n };\n\n for (const inputPath of markdownFiles) {\n try {\n const pageResult = await transformSsgPage(context, inputPath);\n collected.pageResults.push(pageResult);\n collectOgImageEntry(context, pageResult, collected);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n collected.errors.push(`Failed to process ${inputPath}: ${errorMessage}`);\n }\n }\n\n return collected;\n}\n\nasync function transformSsgPage(\n context: BuildSsgContext,\n inputPath: string,\n): Promise<PageProcessResult> {\n const content = await fs.readFile(inputPath, \"utf-8\");\n const result = await transformMarkdown(content, inputPath, context.options, {\n convertMdLinks: true,\n baseUrl: context.base,\n sourcePath: inputPath,\n });\n const frontmatter = normalizeVitePressFrontmatter(result.frontmatter);\n const transformedHtml = await transformSsgHtml(result.html, context.options);\n const title = extractTitle(transformedHtml, frontmatter);\n\n return {\n inputPath,\n routePaths: getRoutePaths(\n inputPath,\n context.srcDir,\n context.outDir,\n context.base,\n context.ssgOptions.extension,\n context.ssgOptions.siteUrl,\n ),\n transformedHtml,\n title,\n description: frontmatter.description as string | undefined,\n lastUpdated: context.napi?.getGitLastUpdated(inputPath, context.root) ?? undefined,\n frontmatter,\n toc: result.toc,\n };\n}\n\nasync function transformSsgHtml(html: string, options: ResolvedOptions): Promise<string> {\n const { html: protectedHtml, svgs: mermaidSvgs } = protectMermaidSvgs(html);\n const pluginOptions: TransformAllOptions = {\n tabs: true,\n youtube: true,\n github: options.embeds.github,\n openGraph: options.embeds.openGraph,\n pm: options.embeds.pm,\n spotify: options.embeds.spotify,\n stackBlitz: options.embeds.stackBlitz,\n twitter: options.embeds.twitter,\n bluesky: options.embeds.bluesky,\n webContainer: options.embeds.webContainer,\n mermaid: true,\n githubToken: process.env.GITHUB_TOKEN,\n };\n\n let transformedHtml = await transformAllPlugins(protectedHtml, pluginOptions);\n if (hasIslands(transformedHtml)) {\n const islandResult = await transformIslands(transformedHtml);\n transformedHtml = islandResult.html;\n }\n\n return restoreMermaidSvgs(transformedHtml, mermaidSvgs);\n}\n\nfunction collectOgImageEntry(\n context: BuildSsgContext,\n pageResult: PageProcessResult,\n collected: CollectedPageResults,\n): void {\n if (!context.shouldGenerateOgImages) {\n return;\n }\n\n const { layout: _layout, ...frontmatterRest } = pageResult.frontmatter;\n collected.ogImageEntries.push({\n props: {\n ...frontmatterRest,\n title: pageResult.title,\n description: pageResult.description,\n siteName: context.siteName,\n },\n outputPath: pageResult.routePaths.ogImagePath,\n });\n collected.ogImageInputPaths.push(pageResult.inputPath);\n collected.ogImageUrlMap.set(pageResult.inputPath, pageResult.routePaths.ogImageUrl);\n}\n\nasync function generateOgImageAssets(\n context: BuildSsgContext,\n collected: CollectedPageResults,\n generatedFiles: string[],\n errors: string[],\n): Promise<void> {\n if (!context.shouldGenerateOgImages || collected.ogImageEntries.length === 0) {\n return;\n }\n\n try {\n const ogResults = await generateOgImages(\n collected.ogImageEntries,\n context.options.ogImageOptions,\n context.root,\n );\n if (clearMissingBrowserOgImages(ogResults, collected)) {\n return;\n }\n\n reportOgImageResults(ogResults, collected, generatedFiles, errors);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n console.warn(`[ox-content:og-image] Batch generation failed: ${errorMessage}`);\n collected.ogImageUrlMap.clear();\n }\n}\n\nfunction clearMissingBrowserOgImages(\n ogResults: Awaited<ReturnType<typeof generateOgImages>>,\n collected: CollectedPageResults,\n): boolean {\n const allMissingBrowser =\n ogResults.length > 0 && ogResults.every((result) => result.error === \"Chromium not available\");\n if (!allMissingBrowser) {\n return false;\n }\n\n for (const inputPath of collected.ogImageInputPaths) {\n collected.ogImageUrlMap.delete(inputPath);\n }\n return true;\n}\n\nfunction reportOgImageResults(\n ogResults: Awaited<ReturnType<typeof generateOgImages>>,\n collected: CollectedPageResults,\n generatedFiles: string[],\n errors: string[],\n): void {\n let ogSuccessCount = 0;\n\n for (let i = 0; i < ogResults.length; i++) {\n const result = ogResults[i];\n if (result.error) {\n errors.push(`OG image failed for ${result.outputPath}: ${result.error}`);\n collected.ogImageUrlMap.delete(collected.ogImageInputPaths[i]);\n } else {\n generatedFiles.push(result.outputPath);\n ogSuccessCount++;\n }\n }\n\n if (ogSuccessCount > 0) {\n const cachedCount = ogResults.filter((result) => result.cached && !result.error).length;\n console.log(\n `[ox-content:og-image] Generated ${ogSuccessCount} OG images` +\n (cachedCount > 0 ? ` (${cachedCount} from cache)` : \"\"),\n );\n }\n}\n\nasync function generateHtmlPages(\n context: BuildSsgContext,\n pageResults: PageProcessResult[],\n collected: CollectedPageResults,\n errors: string[],\n): Promise<GeneratedHtmlPage[]> {\n const generatedPages: GeneratedHtmlPage[] = [];\n\n for (const pageResult of pageResults) {\n try {\n generatedPages.push({\n inputPath: pageResult.inputPath,\n outputPath: pageResult.routePaths.outputPath,\n html: await renderSsgPage(context, pageResult, collected.ogImageUrlMap),\n });\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n errors.push(`Failed to generate HTML for ${pageResult.inputPath}: ${errorMessage}`);\n }\n }\n\n return generatedPages;\n}\n\nasync function renderSsgPage(\n context: BuildSsgContext,\n pageResult: PageProcessResult,\n ogImageUrlMap: Map<string, string>,\n): Promise<string> {\n if (context.ssgOptions.bare) {\n return generateBareHtmlPage(pageResult.transformedHtml, pageResult.title);\n }\n\n const pageData = createSsgPageData(pageResult);\n const pageOgImage =\n context.shouldGenerateOgImages && ogImageUrlMap.has(pageResult.inputPath)\n ? ogImageUrlMap.get(pageResult.inputPath)\n : context.ssgOptions.ogImage;\n\n return generateHtmlPage(\n pageData,\n context.navItems,\n context.siteName,\n context.base,\n pageOgImage,\n context.ssgOptions.theme,\n getPageLocale(pageData.path, context.options.i18n),\n context.options.i18n ? context.options.i18n.locales : undefined,\n );\n}\n\nfunction createSsgPageData(pageResult: PageProcessResult): SsgPageData {\n const { frontmatter } = pageResult;\n const entryPage =\n frontmatter.layout === \"entry\"\n ? {\n hero: frontmatter.hero as HeroConfig | undefined,\n features: frontmatter.features as FeatureConfig[] | undefined,\n }\n : undefined;\n\n return {\n title: pageResult.title,\n description: pageResult.description,\n content: pageResult.transformedHtml,\n toc: pageResult.toc,\n lastUpdated: pageResult.lastUpdated,\n frontmatter,\n path: pageResult.routePaths.urlPath,\n href: pageResult.routePaths.href,\n entryPage,\n };\n}\n\nasync function writeGeneratedPages(\n generatedPages: GeneratedHtmlPage[],\n context: BuildSsgContext,\n generatedFiles: string[],\n): Promise<void> {\n const optimizedOutput = await externalizeSharedPageAssets(\n generatedPages,\n context.outDir,\n context.base,\n );\n generatedFiles.push(...optimizedOutput.assets);\n\n for (const page of optimizedOutput.pages) {\n await fs.mkdir(path.dirname(page.outputPath), { recursive: true });\n await fs.writeFile(page.outputPath, page.html, \"utf-8\");\n generatedFiles.push(page.outputPath);\n }\n}\n","/**\n * Full-text search functionality for Ox Content.\n *\n * Generates search index at build time and provides client-side search.\n */\n\nimport { importNapiModule, importNapiModuleSync } from \"./napi\";\nimport { DEFAULT_MARKDOWN_EXTENSIONS } from \"./markdown\";\nimport type {\n SearchOptions,\n ResolvedSearchOptions,\n SearchDocument,\n ScopedSearchQuery,\n} from \"./types\";\n\n// Import Rust bindings\nlet oxContent: typeof import(\"@ox-content/napi\") | null = null;\n\nasync function getOxContent() {\n if (!oxContent) {\n try {\n oxContent = await importNapiModule();\n } catch {\n console.warn(\"[ox-content] Native bindings not available, search disabled\");\n return null;\n }\n }\n return oxContent;\n}\n\n/**\n * Splits a raw query into free-text terms and `@scope` prefixes.\n */\nexport function parseScopedSearchQuery(query: string): ScopedSearchQuery {\n return importNapiModuleSync().parseScopedSearchQuery(query);\n}\n\n/**\n * Derives hierarchical search scopes from a document id or URL.\n *\n * For example, `api/math/index` yields `[\"api\", \"api/math\"]`.\n */\nexport function getSearchDocumentScopes(doc: Pick<SearchDocument, \"id\" | \"url\">): string[] {\n return importNapiModuleSync().getSearchDocumentScopes(doc.id ?? \"\", doc.url ?? \"\");\n}\n\n/**\n * Returns true when a search document belongs to at least one requested scope.\n */\nexport function matchesSearchScopes(\n doc: Pick<SearchDocument, \"id\" | \"url\">,\n scopes: string[],\n): boolean {\n return importNapiModuleSync().matchesSearchScopes(doc.id ?? \"\", doc.url ?? \"\", scopes);\n}\n\n/**\n * Resolves search options with defaults.\n */\nexport function resolveSearchOptions(\n options: SearchOptions | boolean | undefined,\n): ResolvedSearchOptions {\n if (options === false) {\n return {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search documentation...\",\n hotkey: \"/\",\n };\n }\n\n const opts = typeof options === \"object\" ? options : {};\n\n return {\n enabled: opts.enabled ?? true,\n limit: opts.limit ?? 10,\n prefix: opts.prefix ?? true,\n placeholder: opts.placeholder ?? \"Search documentation...\",\n hotkey: opts.hotkey ?? \"/\",\n };\n}\n\n/**\n * Builds the search index from Markdown files.\n */\nexport async function buildSearchIndex(\n srcDir: string,\n base: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): Promise<string> {\n const napi = await getOxContent();\n\n if (!napi) {\n return JSON.stringify({\n documents: [],\n index: {},\n df: {},\n avg_dl: 0,\n doc_count: 0,\n });\n }\n\n return napi.buildSearchIndexFromDirectory(srcDir, base, [...extensions]);\n}\n\n/**\n * Writes the search index to a file.\n */\nexport async function writeSearchIndex(indexJson: string, outDir: string): Promise<void> {\n const napi = await getOxContent();\n\n if (!napi) {\n return;\n }\n\n napi.writeSearchIndex(indexJson, outDir);\n}\n\n/**\n * Client-side search module code.\n * This is injected into the bundle as a virtual module.\n */\nexport function generateSearchModule(options: ResolvedSearchOptions, indexPath: string): string {\n return importNapiModuleSync().generateSearchModuleFromOptions(options, indexPath);\n}\n","/**\n * Dev server middleware for ox-content SSG.\n *\n * Serves fully-rendered HTML pages (with navigation, theme, etc.)\n * during `vite dev`, matching the SSG build output.\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport type { Connect } from \"vite\";\nimport { transformMarkdown } from \"./transform\";\nimport { transformAllPlugins } from \"./plugins\";\nimport { resetTabGroupCounter } from \"./plugins\";\nimport { protectMermaidSvgs, restoreMermaidSvgs } from \"./plugins/mermaid-protect\";\nimport { transformIslands, hasIslands, resetIslandCounter } from \"./island\";\nimport {\n collectMarkdownFiles,\n buildNavItems,\n buildThemeNavItems,\n extractTitle,\n getUrlPath,\n generateHtmlPage,\n formatTitle,\n resolveNavigationGroups,\n} from \"./ssg\";\nimport type { NavGroup, SsgPageData, SsgEntryPageConfig } from \"./ssg\";\nimport type { ResolvedOptions } from \"./types\";\nimport type { HeroConfig, FeatureConfig } from \"./types\";\nimport { normalizeVitePressFrontmatter } from \"./vitepress\";\nimport { isMarkdownFilePath } from \"./markdown\";\n\n/** File extensions to skip in the middleware. */\nconst SKIP_EXTENSIONS = new Set([\n \".js\",\n \".ts\",\n \".css\",\n \".scss\",\n \".less\",\n \".svg\",\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".json\",\n \".map\",\n \".mp4\",\n \".webm\",\n \".mp3\",\n \".pdf\",\n]);\n\n/** Vite internal URL prefixes to skip. */\nconst VITE_INTERNAL_PREFIXES = [\"/@vite/\", \"/@fs/\", \"/@id/\", \"/__\"];\n\n/**\n * Check if a request URL should be skipped by the dev server middleware.\n */\nfunction shouldSkip(url: string): boolean {\n // Skip Vite internal URLs\n for (const prefix of VITE_INTERNAL_PREFIXES) {\n if (url.startsWith(prefix)) return true;\n }\n\n // Skip node_modules\n if (url.includes(\"/node_modules/\")) return true;\n\n // Skip requests with known static file extensions\n const extMatch = url.match(/\\.([a-zA-Z0-9]+)(?:\\?|$)/);\n if (extMatch) {\n const ext = \".\" + extMatch[1].toLowerCase();\n if (SKIP_EXTENSIONS.has(ext)) return true;\n }\n\n return false;\n}\n\n/**\n * Resolve a request URL to a markdown file path.\n * Returns null if no matching file exists.\n */\nasync function resolveMarkdownFile(\n url: string,\n srcDir: string,\n extensions: readonly string[],\n): Promise<string | null> {\n // Remove query string and hash\n let pathname = url.split(\"?\")[0].split(\"#\")[0];\n\n // Remove trailing /index.html\n if (pathname.endsWith(\"/index.html\")) {\n pathname = pathname.slice(0, -\"/index.html\".length) || \"/\";\n }\n\n // Remove trailing slash (except for root)\n if (pathname !== \"/\" && pathname.endsWith(\"/\")) {\n pathname = pathname.slice(0, -1);\n }\n\n const routePath = pathname === \"/\" ? \"\" : pathname.slice(1);\n const directCandidates =\n pathname === \"/\"\n ? extensions.map((extension) => `index${extension}`)\n : isMarkdownFilePath(routePath, extensions)\n ? [routePath]\n : extensions.map((extension) => `${routePath}${extension}`);\n\n for (const relativePath of directCandidates) {\n const filePath = path.join(srcDir, relativePath);\n try {\n await fs.access(filePath);\n return filePath;\n } catch {\n // Try the next extension.\n }\n }\n\n for (const extension of extensions) {\n const indexPath = path.join(srcDir, routePath, `index${extension}`);\n try {\n await fs.access(indexPath);\n return indexPath;\n } catch {\n // Try the next extension.\n }\n }\n\n return null;\n}\n\n/**\n * Inject Vite HMR client script into the HTML.\n */\nfunction injectViteHmrClient(html: string): string {\n const hmrScript = `<script type=\"module\" src=\"/@vite/client\"></script>\n<script type=\"module\">\nif (import.meta.hot) {\n const reexecuteBodyScripts = () => {\n const scripts = Array.from(document.body.querySelectorAll('script'));\n for (const script of scripts) {\n const nextScript = document.createElement('script');\n for (const attr of script.attributes) {\n nextScript.setAttribute(attr.name, attr.value);\n }\n nextScript.textContent = script.textContent;\n script.replaceWith(nextScript);\n }\n };\n\n const applyHotUpdate = async () => {\n const nextUrl = new URL(window.location.href);\n nextUrl.searchParams.set('__ox_hmr', String(Date.now()));\n\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n const theme = document.documentElement.getAttribute('data-theme');\n\n const response = await fetch(nextUrl.toString(), {\n cache: 'no-store',\n headers: {\n 'x-ox-content-hmr': '1',\n },\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch updated page');\n }\n\n const nextHtml = await response.text();\n const nextDocument = new DOMParser().parseFromString(nextHtml, 'text/html');\n\n if (!nextDocument.body) {\n throw new Error('Updated page is missing a body');\n }\n\n document.title = nextDocument.title;\n document.body.innerHTML = nextDocument.body.innerHTML;\n reexecuteBodyScripts();\n\n if (theme) {\n document.documentElement.setAttribute('data-theme', theme);\n }\n\n window.scrollTo({ left: scrollX, top: scrollY });\n };\n\n let pendingUpdate = Promise.resolve();\n\n import.meta.hot.on('ox-content:update', () => {\n pendingUpdate = pendingUpdate\n .then(() => applyHotUpdate())\n .catch((error) => {\n console.warn('[ox-content] HMR patch failed, falling back to reload.', error);\n location.reload();\n });\n });\n}\n</script>`;\n\n return html.replace(\"</head>\", hmrScript + \"\\n</head>\");\n}\n\n/**\n * Dev server state for caching.\n */\ninterface DevServerCache {\n /** Cached navigation groups. Invalidated on file add/unlink. */\n navGroups: NavGroup[] | null;\n /** Cached rendered HTML keyed by absolute file path. */\n pages: Map<string, string>;\n /** Cached site name. Computed once. */\n siteName: string | null;\n}\n\n/**\n * Create a dev server cache instance.\n */\nexport function createDevServerCache(): DevServerCache {\n return {\n navGroups: null,\n pages: new Map(),\n siteName: null,\n };\n}\n\n/**\n * Invalidate navigation cache (called on file add/unlink).\n */\nexport function invalidateNavCache(cache: DevServerCache): void {\n cache.navGroups = null;\n // Also clear all page caches since navigation HTML is embedded in pages\n cache.pages.clear();\n}\n\n/**\n * Invalidate page cache for a specific file (called on file change).\n */\nexport function invalidatePageCache(cache: DevServerCache, filePath: string): void {\n cache.pages.delete(filePath);\n}\n\n/**\n * Resolve site name from options or package.json.\n */\nasync function resolveSiteName(options: ResolvedOptions, root: string): Promise<string> {\n if (options.ssg.siteName) {\n return options.ssg.siteName;\n }\n\n try {\n const pkgPath = path.join(root, \"package.json\");\n const pkg = JSON.parse(await fs.readFile(pkgPath, \"utf-8\"));\n if (pkg.name) {\n return formatTitle(pkg.name);\n }\n } catch {\n // Use default\n }\n\n return \"Documentation\";\n}\n\n/**\n * Render a single markdown page to full HTML.\n */\nasync function renderPage(\n filePath: string,\n options: ResolvedOptions,\n navGroups: NavGroup[],\n siteName: string,\n base: string,\n root: string,\n): Promise<string> {\n const srcDir = path.resolve(root, options.srcDir);\n\n // Reset counters for clean render\n resetTabGroupCounter();\n resetIslandCounter();\n\n // Read markdown content\n const content = await fs.readFile(filePath, \"utf-8\");\n\n // Transform markdown to HTML\n const result = await transformMarkdown(content, filePath, options, {\n convertMdLinks: true,\n baseUrl: base,\n sourcePath: filePath,\n });\n const frontmatter = normalizeVitePressFrontmatter(result.frontmatter);\n\n let transformedHtml = result.html;\n\n // Protect mermaid SVGs from rehype processing\n const { html: protectedHtml, svgs: mermaidSvgs } = protectMermaidSvgs(transformedHtml);\n transformedHtml = protectedHtml;\n\n // Transform all plugins\n transformedHtml = await transformAllPlugins(transformedHtml, {\n tabs: true,\n youtube: true,\n github: options.embeds.github,\n openGraph: options.embeds.openGraph,\n pm: options.embeds.pm,\n spotify: options.embeds.spotify,\n stackBlitz: options.embeds.stackBlitz,\n twitter: options.embeds.twitter,\n bluesky: options.embeds.bluesky,\n webContainer: options.embeds.webContainer,\n mermaid: true,\n githubToken: process.env.GITHUB_TOKEN,\n });\n\n // Transform Island components\n if (hasIslands(transformedHtml)) {\n const islandResult = await transformIslands(transformedHtml);\n transformedHtml = islandResult.html;\n }\n\n // Restore protected mermaid SVGs\n transformedHtml = restoreMermaidSvgs(transformedHtml, mermaidSvgs);\n\n // Extract title\n const title = extractTitle(transformedHtml, frontmatter);\n const description = frontmatter.description as string | undefined;\n\n // Check if this is an entry page\n let entryPage: SsgEntryPageConfig | undefined;\n if (frontmatter.layout === \"entry\") {\n entryPage = {\n hero: frontmatter.hero as HeroConfig | undefined,\n features: frontmatter.features as FeatureConfig[] | undefined,\n };\n }\n\n // Build page data\n const pageData: SsgPageData = {\n title,\n description,\n content: transformedHtml,\n toc: result.toc,\n frontmatter,\n path: getUrlPath(filePath, srcDir),\n href: getUrlPath(filePath, srcDir) || \"/\",\n entryPage,\n };\n\n // Generate full HTML page\n let html = await generateHtmlPage(\n pageData,\n navGroups,\n siteName,\n base,\n options.ssg.ogImage,\n options.ssg.theme,\n );\n\n // Inject Vite HMR client for live reload\n html = injectViteHmrClient(html);\n\n return html;\n}\n\n/**\n * Create the dev server middleware for SSG page serving.\n */\nexport function createDevServerMiddleware(\n options: ResolvedOptions,\n root: string,\n cache: DevServerCache,\n): Connect.NextHandleFunction {\n const srcDir = path.resolve(root, options.srcDir);\n const base = options.base.endsWith(\"/\") ? options.base : options.base + \"/\";\n\n return async (req, res, next) => {\n const url = req.url;\n if (!url) return next();\n\n // Strip base from URL for routing\n let routeUrl = url;\n if (base !== \"/\" && routeUrl.startsWith(base)) {\n routeUrl = \"/\" + routeUrl.slice(base.length);\n }\n\n // Skip non-page requests\n if (shouldSkip(routeUrl)) return next();\n\n // Resolve markdown file\n const filePath = await resolveMarkdownFile(routeUrl, srcDir, options.extensions);\n if (!filePath) return next();\n\n try {\n // Check page cache\n const cached = cache.pages.get(filePath);\n if (cached) {\n res.setHeader(\"Content-Type\", \"text/html\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.end(cached);\n return;\n }\n\n // Resolve site name (cached after first call)\n if (!cache.siteName) {\n cache.siteName = await resolveSiteName(options, root);\n }\n\n // Build navigation if not cached\n if (!cache.navGroups) {\n const markdownFiles = await collectMarkdownFiles(srcDir, options.extensions);\n cache.navGroups =\n resolveNavigationGroups(options.ssg.navigation, base, options.ssg.extension) ??\n (options.ssg.theme?.sidebar.length\n ? buildThemeNavItems(options.ssg.theme.sidebar, base, options.ssg.extension)\n : buildNavItems(markdownFiles, srcDir, base, options.ssg.extension));\n }\n\n // Render the page\n const html = await renderPage(filePath, options, cache.navGroups, cache.siteName, base, root);\n\n // Cache the result\n cache.pages.set(filePath, html);\n\n res.setHeader(\"Content-Type\", \"text/html\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.end(html);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`[ox-content:dev] Failed to render ${filePath}:`, message);\n next();\n }\n };\n}\n","/**\n * OG Viewer - Dev tool for previewing Open Graph metadata\n *\n * Accessible at /__og-viewer during development.\n * Shows all pages with their OG metadata, validation warnings,\n * and social card previews.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { glob } from \"glob\";\nimport type { Plugin } from \"vite\";\nimport type { ResolvedOptions } from \"./types\";\nimport { normalizeVitePressFrontmatter } from \"./vitepress\";\nimport { markdownGlobPattern, stripMarkdownExtension } from \"./markdown\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface PageOgData {\n path: string;\n urlPath: string;\n title: string;\n description: string;\n author: string;\n tags: string[];\n ogImageUrl: string;\n warnings: { level: \"error\" | \"warning\"; message: string }[];\n}\n\n// =============================================================================\n// Data Collection\n// =============================================================================\n\nfunction parseFrontmatter(content: string): Record<string, unknown> {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!match) return {};\n\n const yaml = match[1];\n const result: Record<string, unknown> = {};\n\n for (const line of yaml.split(\"\\n\")) {\n const kv = line.match(/^(\\w[\\w-]*):\\s*(.*)$/);\n if (!kv) continue;\n const [, key, rawValue] = kv;\n let value: unknown = rawValue.trim();\n\n // Handle arrays (simple inline: [a, b])\n if (typeof value === \"string\" && value.startsWith(\"[\") && value.endsWith(\"]\")) {\n value = value\n .slice(1, -1)\n .split(\",\")\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, \"\"))\n .filter(Boolean);\n }\n // Strip quotes\n else if (typeof value === \"string\" && /^['\"].*['\"]$/.test(value)) {\n value = value.slice(1, -1);\n }\n // Booleans\n else if (value === \"true\") value = true;\n else if (value === \"false\") value = false;\n\n result[key] = value;\n }\n\n return result;\n}\n\nfunction extractTitle(content: string, frontmatter: Record<string, unknown>): string {\n if (typeof frontmatter.title === \"string\" && frontmatter.title) {\n return frontmatter.title;\n }\n // Fallback: first # heading\n const match = content.match(/^#\\s+(.+)$/m);\n return match ? match[1].trim() : \"\";\n}\n\nfunction getUrlPath(filePath: string, srcDir: string, extensions: readonly string[]): string {\n let rel = path.relative(srcDir, filePath).replace(/\\\\/g, \"/\");\n rel = stripMarkdownExtension(rel, extensions);\n if (rel === \"index\") return \"/\";\n if (rel.endsWith(\"/index\")) rel = rel.slice(0, -\"/index\".length);\n return \"/\" + rel;\n}\n\nfunction computeOgImageUrl(\n urlPath: string,\n base: string,\n siteUrl?: string,\n generateOgImage?: boolean,\n staticOgImage?: string,\n): string {\n if (!generateOgImage) return staticOgImage || \"\";\n\n const cleanBase = base.endsWith(\"/\") ? base : base + \"/\";\n let relativePath: string;\n if (urlPath === \"/\") {\n relativePath = `${cleanBase}og-image.png`;\n } else {\n relativePath = `${cleanBase}${urlPath.replace(/^\\//, \"\")}/og-image.png`;\n }\n\n if (siteUrl) {\n const cleanSiteUrl = siteUrl.replace(/\\/$/, \"\");\n return `${cleanSiteUrl}${relativePath}`;\n }\n return relativePath;\n}\n\nfunction validatePage(\n page: { title: string; description: string; ogImageUrl: string },\n options: ResolvedOptions,\n): { level: \"error\" | \"warning\"; message: string }[] {\n const warnings: { level: \"error\" | \"warning\"; message: string }[] = [];\n\n if (!page.title) {\n warnings.push({ level: \"error\", message: \"title is missing\" });\n } else if (page.title.length > 70) {\n warnings.push({ level: \"warning\", message: `title is too long (${page.title.length}/70)` });\n }\n\n if (!page.description) {\n warnings.push({ level: \"warning\", message: \"description is missing\" });\n } else if (page.description.length > 200) {\n warnings.push({\n level: \"warning\",\n message: `description is too long (${page.description.length}/200)`,\n });\n }\n\n const generateOgImage = options.ogImage || options.ssg.generateOgImage;\n if (generateOgImage && !options.ssg.siteUrl) {\n warnings.push({ level: \"warning\", message: \"ogImage enabled but siteUrl is not set\" });\n }\n\n return warnings;\n}\n\nasync function collectPages(options: ResolvedOptions, root: string): Promise<PageOgData[]> {\n const srcDir = path.resolve(root, options.srcDir);\n const files = await glob(markdownGlobPattern(srcDir, options.extensions), { absolute: true });\n\n const pages: PageOgData[] = [];\n const generateOgImage = options.ogImage || options.ssg.generateOgImage;\n\n for (const file of files.sort()) {\n const content = fs.readFileSync(file, \"utf-8\");\n const frontmatter = normalizeVitePressFrontmatter(parseFrontmatter(content));\n\n // Skip entry layout pages (they are landing pages, not content pages)\n if (frontmatter.layout === \"entry\") continue;\n\n const title = extractTitle(content, frontmatter);\n const description = typeof frontmatter.description === \"string\" ? frontmatter.description : \"\";\n const author = typeof frontmatter.author === \"string\" ? frontmatter.author : \"\";\n const tags = Array.isArray(frontmatter.tags)\n ? (frontmatter.tags as string[])\n : typeof frontmatter.tags === \"string\"\n ? [frontmatter.tags]\n : [];\n\n const urlPath = getUrlPath(file, srcDir, options.extensions);\n const ogImageUrl = computeOgImageUrl(\n urlPath,\n options.base,\n options.ssg.siteUrl,\n generateOgImage,\n options.ssg.ogImage,\n );\n\n const page = {\n path: path.relative(srcDir, file),\n urlPath,\n title,\n description,\n author,\n tags,\n ogImageUrl,\n warnings: [] as PageOgData[\"warnings\"],\n };\n page.warnings = validatePage(page, options);\n pages.push(page);\n }\n\n return pages;\n}\n\n// =============================================================================\n// HTML Rendering\n// =============================================================================\n\nfunction renderViewerHtml(pages: PageOgData[], options: ResolvedOptions): string {\n const generateOgImage = options.ogImage || options.ssg.generateOgImage;\n const totalWarnings = pages.reduce(\n (sum, p) => sum + p.warnings.filter((w) => w.level === \"warning\").length,\n 0,\n );\n const totalErrors = pages.reduce(\n (sum, p) => sum + p.warnings.filter((w) => w.level === \"error\").length,\n 0,\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>OG Viewer - ox-content</title>\n <style>\n :root {\n --bg: #ffffff;\n --bg-card: #f5f7fb;\n --bg-preview: #ffffff;\n --text: #131a30;\n --text-muted: #4f607b;\n --border: #d2dbea;\n --accent: #4f6fae;\n --accent-light: #eef2fa;\n --error: #dc2626;\n --error-bg: #fef2f2;\n --warning: #d97706;\n --warning-bg: #fffbeb;\n --success: #16a34a;\n --tag-bg: #ecf3ff;\n --radius: 16px;\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --bg: #060816;\n --bg-card: #0d1528;\n --bg-preview: #10172d;\n --text: #ebf2ff;\n --text-muted: #8ea0bf;\n --border: #223252;\n --accent: #86a4da;\n --accent-light: #151730;\n --error: #f87171;\n --error-bg: #450a0a;\n --warning: #fbbf24;\n --warning-bg: #451a03;\n --success: #4ade80;\n --tag-bg: #131b33;\n }\n }\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: 'IBM Plex Sans', 'Avenir Next', 'Segoe UI', system-ui, sans-serif; background: radial-gradient(circle at top left, rgba(79,111,174,0.10), transparent 24%), radial-gradient(circle at 85% 14%, rgba(145,237,233,0.08), transparent 22%), var(--bg); color: var(--text); }\n .header { padding: 16px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }\n .header svg { width: 28px; height: 28px; color: var(--accent); }\n .header h1 { font-size: 18px; font-weight: 600; }\n .header h1 span { color: var(--text-muted); font-weight: 400; }\n .header-actions { margin-left: auto; }\n .btn { padding: 6px 14px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-card); color: var(--text); cursor: pointer; font-size: 13px; transition: all 0.15s; }\n .btn:hover { border-color: var(--accent); color: var(--accent); }\n .summary { padding: 12px 24px; display: flex; gap: 20px; border-bottom: 1px solid var(--border); font-size: 13px; color: var(--text-muted); flex-wrap: wrap; align-items: center; }\n .summary-item { display: flex; align-items: center; gap: 4px; }\n .summary-item strong { color: var(--text); }\n .summary-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }\n .dot-error { background: var(--error); }\n .dot-warning { background: var(--warning); }\n .dot-success { background: var(--success); }\n .toolbar { padding: 12px 24px; display: flex; gap: 8px; border-bottom: 1px solid var(--border); flex-wrap: wrap; align-items: center; }\n .filter-btn { padding: 4px 12px; border: 1px solid var(--border); border-radius: 16px; background: transparent; color: var(--text-muted); cursor: pointer; font-size: 12px; transition: all 0.15s; }\n .filter-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }\n .search-input { padding: 6px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--text); font-size: 13px; flex: 1; min-width: 200px; }\n .search-input::placeholder { color: var(--text-muted); }\n .container { padding: 24px; display: flex; flex-direction: column; gap: 20px; max-width: 1200px; margin: 0 auto; }\n .card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-card); overflow: hidden; }\n .card-header { padding: 16px; border-bottom: 1px solid var(--border); }\n .card-path { font-size: 12px; color: var(--text-muted); font-family: monospace; margin-bottom: 4px; }\n .card-title { font-size: 16px; font-weight: 600; }\n .card-desc { font-size: 13px; color: var(--text-muted); margin-top: 4px; }\n .card-meta { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; align-items: center; }\n .tag { padding: 2px 8px; background: var(--tag-bg); border-radius: 4px; font-size: 11px; color: var(--text-muted); }\n .card-warnings { padding: 8px 16px; display: flex; flex-direction: column; gap: 4px; }\n .warning-item { font-size: 12px; padding: 4px 8px; border-radius: 4px; }\n .warning-item.error { background: var(--error-bg); color: var(--error); }\n .warning-item.warning { background: var(--warning-bg); color: var(--warning); }\n .card-previews { padding: 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n @media (max-width: 768px) { .card-previews { grid-template-columns: 1fr; } }\n .preview { border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }\n .preview-label { padding: 6px 10px; font-size: 11px; font-weight: 600; color: var(--text-muted); background: var(--bg); border-bottom: 1px solid var(--border); text-transform: uppercase; letter-spacing: 0.5px; }\n .preview-card { background: var(--bg-preview); }\n .preview-img { width: 100%; aspect-ratio: 1200/630; background: linear-gradient(135deg, var(--accent-light), var(--bg-card)); display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 12px; overflow: hidden; }\n .preview-img img { width: 100%; height: 100%; object-fit: cover; }\n .preview-body { padding: 10px 12px; }\n .preview-url { font-size: 11px; color: var(--text-muted); margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .preview-title { font-size: 14px; font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }\n .preview-desc { font-size: 12px; color: var(--text-muted); margin-top: 2px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }\n .empty { text-align: center; padding: 60px; color: var(--text-muted); }\n .spin { animation: spin 0.6s linear infinite; }\n @keyframes spin { to { transform: rotate(360deg); } }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/></svg>\n <h1>OG Viewer <span>/ ox-content</span></h1>\n <div class=\"header-actions\">\n <button class=\"btn\" id=\"refresh-btn\" onclick=\"refresh()\">Refresh</button>\n </div>\n </div>\n <div class=\"summary\" id=\"summary\">\n <div class=\"summary-item\"><strong id=\"s-pages\">${pages.length}</strong>&nbsp;pages</div>\n <div class=\"summary-item\"><span class=\"summary-dot dot-error\"></span>&nbsp;<strong id=\"s-errors\">${totalErrors}</strong>&nbsp;errors</div>\n <div class=\"summary-item\"><span class=\"summary-dot dot-warning\"></span>&nbsp;<strong id=\"s-warnings\">${totalWarnings}</strong>&nbsp;warnings</div>\n <div class=\"summary-item\"><span class=\"summary-dot ${generateOgImage ? \"dot-success\" : \"dot-warning\"}\"></span>&nbsp;ogImage: <strong>${generateOgImage ? \"enabled\" : \"disabled\"}</strong></div>\n </div>\n <div class=\"toolbar\">\n <button class=\"filter-btn active\" data-filter=\"all\" onclick=\"setFilter('all')\">All</button>\n <button class=\"filter-btn\" data-filter=\"warnings\" onclick=\"setFilter('warnings')\">Warnings</button>\n <button class=\"filter-btn\" data-filter=\"errors\" onclick=\"setFilter('errors')\">Errors</button>\n <input class=\"search-input\" type=\"text\" placeholder=\"Search pages...\" oninput=\"applyFilters()\" id=\"search-input\">\n </div>\n <div class=\"container\" id=\"container\"></div>\n\n <script>\n let pages = ${JSON.stringify(pages)};\n let currentFilter = 'all';\n\n function setFilter(f) {\n currentFilter = f;\n document.querySelectorAll('.filter-btn').forEach(b => b.classList.toggle('active', b.dataset.filter === f));\n applyFilters();\n }\n\n function applyFilters() {\n const q = document.getElementById('search-input').value.toLowerCase();\n const filtered = pages.filter(p => {\n if (currentFilter === 'errors' && !p.warnings.some(w => w.level === 'error')) return false;\n if (currentFilter === 'warnings' && !p.warnings.length) return false;\n if (q && !p.path.toLowerCase().includes(q) && !p.title.toLowerCase().includes(q) && !p.description.toLowerCase().includes(q)) return false;\n return true;\n });\n renderCards(filtered);\n }\n\n function esc(s) {\n const d = document.createElement('div');\n d.textContent = s;\n return d.innerHTML;\n }\n\n function renderCards(list) {\n const c = document.getElementById('container');\n if (!list.length) {\n c.innerHTML = '<div class=\"empty\">No pages match the current filter.</div>';\n return;\n }\n c.innerHTML = list.map(p => {\n const warnings = p.warnings.map(w =>\n '<div class=\"warning-item ' + w.level + '\">' + (w.level === 'error' ? '\\\\u2716' : '\\\\u26A0') + ' ' + esc(w.message) + '</div>'\n ).join('');\n const tags = p.tags.map(t => '<span class=\"tag\">' + esc(t) + '</span>').join('');\n const author = p.author ? '<span class=\"tag\">by ' + esc(p.author) + '</span>' : '';\n const imgHtml = p.ogImageUrl\n ? '<img src=\"' + esc(p.ogImageUrl) + '\" onerror=\"this.parentNode.innerHTML=\\\\'No OG image\\\\'\">'\n : 'No OG image';\n const siteHost = ${JSON.stringify(options.ssg.siteUrl || \"example.com\")};\n return '<div class=\"card\">'\n + '<div class=\"card-header\">'\n + '<div class=\"card-path\">' + esc(p.path) + ' &rarr; ' + esc(p.urlPath) + '</div>'\n + '<div class=\"card-title\">' + (esc(p.title) || '<em style=\"color:var(--error)\">No title</em>') + '</div>'\n + (p.description ? '<div class=\"card-desc\">' + esc(p.description) + '</div>' : '')\n + (tags || author ? '<div class=\"card-meta\">' + author + tags + '</div>' : '')\n + '</div>'\n + (warnings ? '<div class=\"card-warnings\">' + warnings + '</div>' : '')\n + '<div class=\"card-previews\">'\n + '<div class=\"preview\"><div class=\"preview-label\">Twitter (summary_large_image)</div><div class=\"preview-card\"><div class=\"preview-img\">' + imgHtml + '</div><div class=\"preview-body\"><div class=\"preview-url\">' + esc(siteHost) + '</div><div class=\"preview-title\">' + esc(p.title) + '</div><div class=\"preview-desc\">' + esc(p.description) + '</div></div></div></div>'\n + '<div class=\"preview\"><div class=\"preview-label\">Facebook (Open Graph)</div><div class=\"preview-card\"><div class=\"preview-img\">' + imgHtml + '</div><div class=\"preview-body\"><div class=\"preview-url\">' + esc(siteHost) + '</div><div class=\"preview-title\">' + esc(p.title) + '</div><div class=\"preview-desc\">' + esc(p.description) + '</div></div></div></div>'\n + '</div>'\n + '</div>';\n }).join('');\n }\n\n async function refresh() {\n const btn = document.getElementById('refresh-btn');\n btn.textContent = 'Refreshing...';\n btn.disabled = true;\n try {\n const res = await fetch('/__og-viewer/api/pages');\n pages = await res.json();\n updateSummary();\n applyFilters();\n } catch(e) {\n console.error('Refresh failed:', e);\n } finally {\n btn.textContent = 'Refresh';\n btn.disabled = false;\n }\n }\n\n function updateSummary() {\n document.getElementById('s-pages').textContent = pages.length;\n document.getElementById('s-errors').textContent = pages.reduce((s,p) => s + p.warnings.filter(w => w.level === 'error').length, 0);\n document.getElementById('s-warnings').textContent = pages.reduce((s,p) => s + p.warnings.filter(w => w.level === 'warning').length, 0);\n }\n\n renderCards(pages);\n </script>\n</body>\n</html>`;\n}\n\n// =============================================================================\n// Plugin\n// =============================================================================\n\nexport function createOgViewerPlugin(options: ResolvedOptions): Plugin {\n return {\n name: \"ox-content:og-viewer\",\n apply: \"serve\",\n\n configureServer(server) {\n server.middlewares.use(async (req, res, next) => {\n if (req.url === \"/__og-viewer\" || req.url === \"/__og-viewer/\") {\n const root = server.config.root || process.cwd();\n try {\n const pages = await collectPages(options, root);\n const html = renderViewerHtml(pages, options);\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(html);\n } catch (err) {\n res.statusCode = 500;\n res.end(`OG Viewer error: ${err instanceof Error ? err.message : String(err)}`);\n }\n return;\n }\n\n if (req.url === \"/__og-viewer/api/pages\") {\n const root = server.config.root || process.cwd();\n try {\n const pages = await collectPages(options, root);\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.end(JSON.stringify(pages));\n } catch (err) {\n res.statusCode = 500;\n res.end(JSON.stringify({ error: String(err) }));\n }\n return;\n }\n\n next();\n });\n },\n };\n}\n","/**\n * i18n plugin for Ox Content.\n *\n * Provides:\n * - Dictionary loading and validation at build time\n * - Virtual module for i18n config\n * - Build-time i18n checking\n * - Locale-aware routing middleware for dev server\n */\n\nimport * as path from \"path\";\nimport * as fs from \"fs\";\nimport type { Plugin, ViteDevServer } from \"vite\";\nimport { importNapiModule } from \"./napi\";\nimport type { I18nOptions, ResolvedI18nOptions, LocaleConfig, ResolvedOptions } from \"./types\";\n\n/**\n * Resolves i18n options with defaults.\n */\nexport function resolveI18nOptions(\n options: I18nOptions | false | undefined,\n): ResolvedI18nOptions | false {\n if (options === false) return false;\n if (!options || !options.enabled) {\n return false;\n }\n\n const defaultLocale = options.defaultLocale ?? \"en\";\n const locales: LocaleConfig[] = options.locales ?? [{ code: defaultLocale, name: defaultLocale }];\n\n // Ensure default locale is in the locales list\n if (!locales.some((l) => l.code === defaultLocale)) {\n locales.unshift({ code: defaultLocale, name: defaultLocale });\n }\n\n return {\n enabled: true,\n dir: options.dir ?? \"content/i18n\",\n defaultLocale,\n locales,\n hideDefaultLocale: options.hideDefaultLocale ?? true,\n check: options.check ?? true,\n functionNames: options.functionNames ?? [\"t\", \"$t\"],\n };\n}\n\n/**\n * Creates the i18n sub-plugin for the Vite plugin array.\n */\nexport function createI18nPlugin(resolvedOptions: ResolvedOptions): Plugin {\n const i18nOptions = resolvedOptions.i18n;\n let root = process.cwd();\n\n return {\n name: \"ox-content:i18n\",\n\n configResolved(config) {\n root = config.root;\n },\n\n resolveId(id) {\n if (id === \"virtual:ox-content/i18n\") {\n return \"\\0virtual:ox-content/i18n\";\n }\n return null;\n },\n\n load(id) {\n if (id === \"\\0virtual:ox-content/i18n\") {\n if (!i18nOptions) {\n return `export const i18n = { enabled: false }; export default i18n;`;\n }\n\n return generateI18nModule(i18nOptions, root);\n }\n return null;\n },\n\n async buildStart() {\n if (!i18nOptions || !i18nOptions.check) return;\n\n const dictDir = path.resolve(root, i18nOptions.dir);\n if (!fs.existsSync(dictDir)) {\n console.warn(`[ox-content:i18n] Dictionary directory not found: ${dictDir}`);\n return;\n }\n\n try {\n const { checkI18nProject } = await importNapiModule();\n const checkResult = checkI18nProject(\n dictDir,\n [path.resolve(root, \"src\"), path.resolve(root, \"content\")],\n i18nOptions.functionNames,\n i18nOptions.defaultLocale,\n );\n if (checkResult.errorCount > 0 || checkResult.warningCount > 0) {\n for (const diag of checkResult.diagnostics) {\n if (diag.severity === \"error\") {\n console.error(`[ox-content:i18n] ${diag.message}`);\n } else if (diag.severity === \"warning\") {\n console.warn(`[ox-content:i18n] ${diag.message}`);\n }\n }\n }\n } catch {\n // NAPI binding not available; skip checks\n }\n },\n\n configureServer(server: ViteDevServer) {\n if (!i18nOptions) return;\n\n // Watch dictionary directory for changes\n const dictDir = path.resolve(root, i18nOptions.dir);\n if (fs.existsSync(dictDir)) {\n server.watcher.add(dictDir);\n\n server.watcher.on(\"change\", (filePath: string) => {\n if (!filePath.startsWith(dictDir)) return;\n if (!/\\.(json|yaml|yml)$/.test(filePath)) return;\n\n // Invalidate the virtual module\n const mod = server.moduleGraph.getModuleById(\"\\0virtual:ox-content/i18n\");\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n }\n\n // Trigger full reload\n server.ws.send({ type: \"full-reload\" });\n });\n }\n\n // Add locale routing middleware\n server.middlewares.use((req, _res, next) => {\n if (!req.url) return next();\n\n // Parse locale from URL\n const url = req.url;\n const localeMatch = url.match(/^\\/([A-Za-z]{2,3}(?:-[A-Za-z0-9]+)*)(\\/|$)/);\n\n if (localeMatch) {\n const localeCode = localeMatch[1];\n const isKnown = i18nOptions.locales.some((l) => l.code === localeCode);\n if (isKnown) {\n // Set locale header for downstream middleware\n (req as any).__oxLocale = localeCode;\n }\n } else if (i18nOptions.hideDefaultLocale) {\n // No locale prefix: use default locale\n (req as any).__oxLocale = i18nOptions.defaultLocale;\n }\n\n next();\n });\n },\n };\n}\n\n/**\n * Generates the virtual module for i18n configuration.\n */\nexport function generateI18nModule(options: ResolvedI18nOptions, root: string): string {\n const dictDir = path.resolve(root, options.dir);\n const config = {\n defaultLocale: options.defaultLocale,\n locales: options.locales,\n hideDefaultLocale: options.hideDefaultLocale,\n };\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const napi = require(\"@ox-content/napi\") as {\n generateI18nModule?: (dictDir: string, runtimeConfig: typeof config) => string;\n };\n\n if (typeof napi.generateI18nModule === \"function\") {\n return napi.generateI18nModule(dictDir, config);\n }\n } catch (error) {\n throw new Error(\n `[ox-content:i18n] Failed to load @ox-content/napi for i18n module generation: ${String(error)}`,\n );\n }\n\n throw new Error(\n \"[ox-content:i18n] @ox-content/napi does not expose generateI18nModule. Please rebuild the NAPI package.\",\n );\n}\n","import { createRequire } from \"node:module\";\nimport type { CSpellUserSettings, SpellCheckFileOptions, ValidationIssue } from \"cspell-lib\";\n\nconst require = createRequire(import.meta.url);\n\nconst SUPPORTED_MARKDOWN_LINT_LANGUAGES = [\"en\", \"ja\", \"zh\", \"fr\", \"de\", \"pl\"] as const;\nconst DEFAULT_LANGUAGES = [\"en\"] as const;\nconst DEFAULT_RULES = {\n duplicateHeadings: true,\n headingIncrement: true,\n maxConsecutiveBlankLines: 1,\n repeatedPunctuation: true,\n repeatedWords: true,\n spellcheck: true,\n trailingSpaces: true,\n} as const;\nconst DEFAULT_CSPELL_IMPORTS: Partial<Record<MarkdownLintLanguage, string>> = {\n de: \"@cspell/dict-de-de/cspell-ext.json\",\n en: \"@cspell/dict-en_us/cspell-ext.json\",\n fr: \"@cspell/dict-fr-fr/cspell-ext.json\",\n pl: \"@cspell/dict-pl_pl/cspell-ext.json\",\n};\n\nexport type MarkdownLintLanguage = (typeof SUPPORTED_MARKDOWN_LINT_LANGUAGES)[number];\nexport type MarkdownLintSeverity = \"error\" | \"warning\" | \"info\";\n\n/**\n * Opt-in standard dictionary sources.\n *\n * The default provider uses CSpell dictionary packages because those packages\n * are actively maintained and expose locale-specific dictionaries in a stable\n * config format. Languages without a bundled preset can still be added through\n * custom `imports`.\n */\nexport interface MarkdownLintStandardDictionaryOptions {\n /**\n * Standard dictionary provider.\n * @default \"cspell\"\n */\n provider?: \"cspell\";\n\n /**\n * Languages whose default standard dictionaries should be enabled.\n *\n * Built-in preset package mappings currently exist for `en`, `fr`, `de`,\n * and `pl`. For other languages, use `imports`.\n *\n * @default []\n */\n languages?: MarkdownLintLanguage[];\n\n /**\n * Additional CSpell-compatible imports.\n *\n * This can point at installed packages like\n * `@cspell/dict-fr-fr/cspell-ext.json` or local CSpell config files.\n */\n imports?: string[];\n\n /**\n * Base URL or path used when resolving `imports`.\n *\n * @default new URL(\".\", import.meta.url)\n */\n resolveImportsRelativeTo?: string | URL;\n}\n\n/**\n * Additional dictionary configuration for the Markdown linter.\n */\nexport interface MarkdownLintDictionaryOptions {\n /**\n * Words ignored across all configured languages.\n */\n words?: string[];\n\n /**\n * Extra words to allow per language.\n */\n byLanguage?: Partial<Record<MarkdownLintLanguage, string[]>>;\n\n /**\n * Words that should never produce diagnostics.\n */\n ignoredWords?: string[];\n\n /**\n * Opt-in standard dictionary datasets.\n *\n * By default the linter stays on a minimal built-in dictionary. Enable this\n * to load larger locale dictionaries from a standard external source.\n */\n standard?: MarkdownLintStandardDictionaryOptions | false;\n}\n\n/**\n * Rule switches for Markdown linting.\n */\nexport interface MarkdownLintRuleOptions {\n /**\n * Report headings that repeat the same visible text.\n * @default true\n */\n duplicateHeadings?: boolean;\n\n /**\n * Report heading depth jumps such as `#` -> `###`.\n * @default true\n */\n headingIncrement?: boolean;\n\n /**\n * Maximum number of blank lines allowed in a row.\n * @default 1\n */\n maxConsecutiveBlankLines?: number;\n\n /**\n * Report duplicated terminal punctuation such as `!!` or `??`.\n * @default true\n */\n repeatedPunctuation?: boolean;\n\n /**\n * Report adjacent repeated words in visible prose.\n * @default true\n */\n repeatedWords?: boolean;\n\n /**\n * Enable built-in multilingual spellchecking.\n * @default true\n */\n spellcheck?: boolean;\n\n /**\n * Report trailing spaces.\n * @default true\n */\n trailingSpaces?: boolean;\n}\n\n/**\n * Options for linting Markdown documents.\n */\nexport interface MarkdownLintOptions {\n /**\n * Languages enabled for spellchecking.\n *\n * When `dictionary.standard.languages` is provided and this option is\n * omitted, those languages are used instead.\n *\n * @default ['en']\n */\n languages?: MarkdownLintLanguage[];\n\n /**\n * Rule configuration.\n */\n rules?: MarkdownLintRuleOptions;\n\n /**\n * Built-in and opt-in standard dictionary overrides.\n */\n dictionary?: MarkdownLintDictionaryOptions;\n}\n\n/**\n * A single Markdown lint diagnostic.\n */\nexport interface MarkdownLintDiagnostic {\n /**\n * Stable rule identifier.\n */\n ruleId: string;\n\n /**\n * Diagnostic severity.\n */\n severity: MarkdownLintSeverity;\n\n /**\n * Human-readable explanation.\n */\n message: string;\n\n /**\n * 1-indexed line number.\n */\n line: number;\n\n /**\n * 1-indexed start column.\n */\n column: number;\n\n /**\n * 1-indexed end line.\n */\n endLine: number;\n\n /**\n * 1-indexed end column.\n */\n endColumn: number;\n\n /**\n * Language used for spellchecking, when relevant.\n */\n language?: MarkdownLintLanguage;\n\n /**\n * Suggested replacements, when available.\n */\n suggestions?: string[];\n}\n\n/**\n * Markdown lint report.\n */\nexport interface MarkdownLintResult {\n /**\n * All collected diagnostics.\n */\n diagnostics: MarkdownLintDiagnostic[];\n\n /**\n * Number of error diagnostics.\n */\n errorCount: number;\n\n /**\n * Number of warning diagnostics.\n */\n warningCount: number;\n\n /**\n * Number of info diagnostics.\n */\n infoCount: number;\n}\n\ninterface NormalizedStandardDictionaryOptions {\n imports: string[];\n languages: MarkdownLintLanguage[];\n provider: \"cspell\";\n resolveImportsRelativeTo: string | URL;\n}\n\ninterface InternalNormalizedMarkdownLintOptions {\n dictionary: Omit<MarkdownLintDictionaryOptions, \"standard\"> & {\n standard: NormalizedStandardDictionaryOptions | false;\n };\n languages: MarkdownLintLanguage[];\n rules: Required<MarkdownLintRuleOptions>;\n}\n\ninterface NapiMarkdownLintLanguageWords {\n language: MarkdownLintLanguage;\n words: string[];\n}\n\ninterface NapiMarkdownLintOptions {\n dictionary?: {\n byLanguage?: NapiMarkdownLintLanguageWords[];\n ignoredWords?: string[];\n words?: string[];\n };\n languages?: MarkdownLintLanguage[];\n rules?: Required<MarkdownLintRuleOptions>;\n}\n\ninterface NapiMarkdownLintResult extends MarkdownLintResult {\n maskedDocument: string;\n}\n\ninterface NapiMarkdownLintModule {\n lintMarkdownDocuments?: (\n sources: string[],\n options?: NapiMarkdownLintOptions,\n ) => NapiMarkdownLintResult[];\n lintMarkdown: (source: string, options?: NapiMarkdownLintOptions) => NapiMarkdownLintResult;\n}\n\nlet napiBinding: NapiMarkdownLintModule | null | undefined;\nlet cspellLibPromise: Promise<typeof import(\"cspell-lib\")> | undefined;\n\n/**\n * Lints Markdown prose with the Rust-backed built-in rule engine.\n */\nexport function lintMarkdown(\n source: string,\n options: MarkdownLintOptions = {},\n): MarkdownLintResult {\n const normalizedOptions = normalizeLintOptions(options);\n return lintMarkdownWithNormalizedOptions(source, normalizedOptions);\n}\n\n/**\n * Async Markdown linter that supports opt-in standard dictionaries.\n */\nexport async function lintMarkdownAsync(\n source: string,\n options: MarkdownLintOptions = {},\n): Promise<MarkdownLintResult> {\n const normalizedOptions = normalizeLintOptions(options);\n const [result] = await lintMarkdownDocumentsWithNormalizedOptions([source], normalizedOptions);\n return result ?? createEmptyLintResult();\n}\n\n/**\n * Internal batched Markdown linting entry point used by file-based workflows.\n */\nexport async function lintMarkdownDocumentsAsync(\n sources: string[],\n options: MarkdownLintOptions = {},\n): Promise<MarkdownLintResult[]> {\n const normalizedOptions = normalizeLintOptions(options);\n return lintMarkdownDocumentsWithNormalizedOptions(sources, normalizedOptions);\n}\n\nfunction lintMarkdownWithNormalizedOptions(\n source: string,\n normalizedOptions: InternalNormalizedMarkdownLintOptions,\n): MarkdownLintResult {\n if (normalizedOptions.dictionary.standard) {\n throw new Error(\n \"[ox-content] lintMarkdownAsync is required when dictionary.standard is enabled.\",\n );\n }\n\n const napi = loadNapiBindingSync();\n return stripMaskedDocument(\n napi.lintMarkdown(source, toNapiMarkdownLintOptions(normalizedOptions)),\n );\n}\n\nasync function lintMarkdownDocumentsWithNormalizedOptions(\n sources: string[],\n normalizedOptions: InternalNormalizedMarkdownLintOptions,\n): Promise<MarkdownLintResult[]> {\n if (sources.length === 0) {\n return [];\n }\n\n const napi = loadNapiBindingSync();\n const napiOptions = toNapiMarkdownLintOptions(\n normalizedOptions,\n Boolean(normalizedOptions.dictionary.standard),\n );\n const builtInResults =\n typeof napi.lintMarkdownDocuments === \"function\"\n ? napi.lintMarkdownDocuments(sources, napiOptions)\n : sources.map((source) => napi.lintMarkdown(source, napiOptions));\n\n if (!normalizedOptions.rules.spellcheck || !normalizedOptions.dictionary.standard) {\n return builtInResults.map(stripMaskedDocument);\n }\n\n const standardDiagnostics = await runStandardSpellcheckDocuments(\n builtInResults.map((result) => result.maskedDocument),\n normalizedOptions,\n );\n\n return builtInResults.map((result, index) =>\n summarizeDiagnostics(\n sortDiagnostics(result.diagnostics.concat(standardDiagnostics[index] ?? [])),\n ),\n );\n}\n\nfunction loadNapiBindingSync(): NapiMarkdownLintModule {\n if (napiBinding) {\n return napiBinding;\n }\n\n if (napiBinding === null) {\n throw new Error(\n \"[ox-content] @ox-content/napi is required for Markdown linting. Please ensure the NAPI module is built.\",\n );\n }\n\n try {\n const loaded = require(\"@ox-content/napi\") as NapiMarkdownLintModule & {\n default?: Partial<NapiMarkdownLintModule>;\n };\n napiBinding =\n loaded.default && typeof loaded.default === \"object\"\n ? { ...loaded.default, ...loaded }\n : loaded;\n\n return napiBinding;\n } catch {\n napiBinding = null;\n throw new Error(\n \"[ox-content] @ox-content/napi is required for Markdown linting. Please ensure the NAPI module is built.\",\n );\n }\n}\n\nfunction toNapiMarkdownLintOptions(\n options: InternalNormalizedMarkdownLintOptions,\n disableBuiltinSpellcheck = false,\n): NapiMarkdownLintOptions {\n const byLanguage = Object.entries(options.dictionary.byLanguage ?? {}).map(\n ([language, words]): NapiMarkdownLintLanguageWords => ({\n language: language as MarkdownLintLanguage,\n words,\n }),\n );\n\n return {\n dictionary: {\n byLanguage,\n ignoredWords: options.dictionary.ignoredWords,\n words: options.dictionary.words,\n },\n languages: options.languages,\n rules: {\n ...options.rules,\n spellcheck: disableBuiltinSpellcheck ? false : options.rules.spellcheck,\n },\n };\n}\n\nfunction stripMaskedDocument(result: NapiMarkdownLintResult): MarkdownLintResult {\n return {\n diagnostics: result.diagnostics,\n errorCount: result.errorCount,\n infoCount: result.infoCount,\n warningCount: result.warningCount,\n };\n}\n\nfunction normalizeLintOptions(options: MarkdownLintOptions): InternalNormalizedMarkdownLintOptions {\n const standardDictionary =\n options.dictionary?.standard && typeof options.dictionary.standard === \"object\"\n ? options.dictionary.standard\n : undefined;\n const optionLanguages = options.languages?.filter((language): language is MarkdownLintLanguage =>\n SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language),\n );\n const standardLanguages = standardDictionary?.languages?.filter(\n (language): language is MarkdownLintLanguage =>\n SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language),\n );\n const languages: MarkdownLintLanguage[] = optionLanguages ??\n standardLanguages ?? [...DEFAULT_LANGUAGES];\n\n const standard = normalizeStandardDictionaryOptions(options.dictionary?.standard, languages);\n\n return {\n dictionary: {\n ...options.dictionary,\n standard,\n },\n languages: [...new Set(languages)],\n rules: {\n duplicateHeadings: options.rules?.duplicateHeadings ?? DEFAULT_RULES.duplicateHeadings,\n headingIncrement: options.rules?.headingIncrement ?? DEFAULT_RULES.headingIncrement,\n maxConsecutiveBlankLines:\n options.rules?.maxConsecutiveBlankLines ?? DEFAULT_RULES.maxConsecutiveBlankLines,\n repeatedPunctuation: options.rules?.repeatedPunctuation ?? DEFAULT_RULES.repeatedPunctuation,\n repeatedWords: options.rules?.repeatedWords ?? DEFAULT_RULES.repeatedWords,\n spellcheck: options.rules?.spellcheck ?? DEFAULT_RULES.spellcheck,\n trailingSpaces: options.rules?.trailingSpaces ?? DEFAULT_RULES.trailingSpaces,\n },\n };\n}\n\nfunction normalizeStandardDictionaryOptions(\n standard: MarkdownLintDictionaryOptions[\"standard\"],\n fallbackLanguages: MarkdownLintLanguage[],\n): NormalizedStandardDictionaryOptions | false {\n if (!standard) {\n return false;\n }\n\n const languages =\n standard.languages?.filter((language): language is MarkdownLintLanguage =>\n SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language),\n ) ?? fallbackLanguages;\n const customImports = standard.imports ?? [];\n const missingPresetLanguages = languages.filter((language) => !DEFAULT_CSPELL_IMPORTS[language]);\n\n if (missingPresetLanguages.length > 0 && customImports.length === 0) {\n throw new Error(\n `[ox-content] No bundled standard dictionary preset exists for ${missingPresetLanguages.join(\n \", \",\n )}. Provide dictionary.standard.imports to enable those languages.`,\n );\n }\n\n const imports = [\n ...languages\n .map((language) => DEFAULT_CSPELL_IMPORTS[language])\n .filter((value): value is string => Boolean(value)),\n ...customImports,\n ];\n\n if (imports.length === 0) {\n throw new Error(\n \"[ox-content] dictionary.standard requires at least one bundled preset language or custom import.\",\n );\n }\n\n return {\n imports: [...new Set(imports)],\n languages: [...new Set(languages)],\n provider: standard.provider ?? \"cspell\",\n resolveImportsRelativeTo: standard.resolveImportsRelativeTo ?? new URL(\".\", import.meta.url),\n };\n}\n\nasync function runStandardSpellcheckDocuments(\n maskedDocuments: string[],\n options: InternalNormalizedMarkdownLintOptions,\n): Promise<MarkdownLintDiagnostic[][]> {\n const standard = options.dictionary.standard;\n\n if (!standard || maskedDocuments.length === 0) {\n return maskedDocuments.map(() => []);\n }\n\n try {\n const { spellCheckDocument } = await loadCspellLib();\n const locale = standard.languages.join(\",\");\n const settings = createStandardSpellcheckSettings(options, locale);\n const spellCheckOptions = {\n generateSuggestions: true,\n noConfigSearch: true,\n numSuggestions: 3,\n resolveImportsRelativeTo: standard.resolveImportsRelativeTo,\n } satisfies SpellCheckFileOptions & { resolveImportsRelativeTo: string | URL };\n\n return Promise.all(\n maskedDocuments.map(async (maskedDocument, index) => {\n if (maskedDocument.trim().length === 0) {\n return [];\n }\n\n const result = await spellCheckDocument(\n {\n languageId: \"plaintext\",\n locale,\n text: maskedDocument,\n uri: `file:///ox-content-lint-${index}.md`,\n },\n spellCheckOptions,\n settings,\n );\n\n // Precompute the document's newline offsets once so each issue's line\n // can be resolved with a binary search instead of a fresh O(N) scan\n // from offset 0 (which made line resolution O(issues * length)).\n const newlineOffsets: number[] = [];\n for (let i = 0; i < maskedDocument.length; i++) {\n if (maskedDocument.charCodeAt(i) === 10) {\n newlineOffsets.push(i);\n }\n }\n\n return result.issues.map((issue) =>\n mapStandardIssueToDiagnostic(issue, standard.languages, newlineOffsets),\n );\n }),\n );\n } catch (error) {\n const imports = standard.imports.join(\", \");\n const message =\n imports.length > 0\n ? `[ox-content] Failed to load standard dictionaries from ${imports}. Verify the imports and install the referenced CSpell packages.`\n : \"[ox-content] Failed to load the configured standard dictionaries.\";\n\n throw new Error(message, {\n cause: error,\n });\n }\n}\n\nfunction createStandardSpellcheckSettings(\n options: InternalNormalizedMarkdownLintOptions,\n locale: string,\n): CSpellUserSettings {\n return {\n import: options.dictionary.standard ? options.dictionary.standard.imports : [],\n ignoreWords: options.dictionary.ignoredWords,\n language: locale,\n version: \"0.2\",\n words: [\n ...(options.dictionary.words ?? []),\n ...Object.values(options.dictionary.byLanguage ?? {}).flat(),\n ],\n };\n}\n\nasync function loadCspellLib(): Promise<typeof import(\"cspell-lib\")> {\n cspellLibPromise ??= import(\"cspell-lib\");\n return cspellLibPromise;\n}\n\nfunction mapStandardIssueToDiagnostic(\n issue: ValidationIssue,\n languages: MarkdownLintLanguage[],\n newlineOffsets: number[],\n): MarkdownLintDiagnostic {\n const line = getLineNumberAtOffset(newlineOffsets, issue.line.offset);\n const column = issue.offset - issue.line.offset + 1;\n const length = issue.length ?? issue.text.length;\n\n return {\n column,\n endColumn: column + length,\n endLine: line,\n language: inferStandardIssueLanguage(issue.text, languages),\n line,\n message: `Unknown word \"${issue.text}\".`,\n ruleId: \"spellcheck\",\n severity: \"warning\",\n suggestions: issue.suggestions?.slice(0, 3),\n };\n}\n\nfunction getLineNumberAtOffset(newlineOffsets: number[], offset: number): number {\n // Line number = 1 + (count of newline offsets strictly less than `offset`).\n // This matches the old linear scan exactly: a newline can only exist at an\n // index < text.length, so counting positions `< offset` over the whole\n // document gives the same count for every `offset` (including past EOF).\n let lo = 0;\n let hi = newlineOffsets.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (newlineOffsets[mid] < offset) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo + 1;\n}\n\nfunction inferStandardIssueLanguage(\n word: string,\n languages: MarkdownLintLanguage[],\n): MarkdownLintLanguage | undefined {\n if (/[\\p{Script=Hiragana}\\p{Script=Katakana}]/u.test(word) && languages.includes(\"ja\")) {\n return \"ja\";\n }\n\n if (/[\\p{Script=Han}]/u.test(word)) {\n if (languages.includes(\"zh\") && !languages.includes(\"ja\")) {\n return \"zh\";\n }\n if (languages.includes(\"ja\") && !languages.includes(\"zh\")) {\n return \"ja\";\n }\n }\n\n if (/[\\p{Script=Latin}]/u.test(word)) {\n const latinLanguages = languages.filter(\n (language): language is Exclude<MarkdownLintLanguage, \"ja\" | \"zh\"> =>\n language !== \"ja\" && language !== \"zh\",\n );\n\n if (latinLanguages.length === 1) {\n return latinLanguages[0];\n }\n\n return inferLatinLanguageFromCharacters(word, latinLanguages);\n }\n\n return undefined;\n}\n\nfunction inferLatinLanguageFromCharacters(\n word: string,\n languages: Exclude<MarkdownLintLanguage, \"ja\" | \"zh\">[],\n): Exclude<MarkdownLintLanguage, \"ja\" | \"zh\"> | undefined {\n if (languages.includes(\"pl\") && /[ąćęłńóśźż]/iu.test(word)) {\n return \"pl\";\n }\n\n if (languages.includes(\"de\") && /[äöüß]/iu.test(word)) {\n return \"de\";\n }\n\n if (languages.includes(\"fr\") && /[àâæçéèêëîïôœùûüÿ]/iu.test(word)) {\n return \"fr\";\n }\n\n return undefined;\n}\n\nfunction summarizeDiagnostics(diagnostics: MarkdownLintDiagnostic[]): MarkdownLintResult {\n let errorCount = 0;\n let warningCount = 0;\n let infoCount = 0;\n\n for (const diagnostic of diagnostics) {\n if (diagnostic.severity === \"error\") {\n errorCount += 1;\n } else if (diagnostic.severity === \"warning\") {\n warningCount += 1;\n } else {\n infoCount += 1;\n }\n }\n\n return { diagnostics, errorCount, infoCount, warningCount };\n}\n\nfunction createEmptyLintResult(): MarkdownLintResult {\n return summarizeDiagnostics([]);\n}\n\nfunction sortDiagnostics(diagnostics: MarkdownLintDiagnostic[]): MarkdownLintDiagnostic[] {\n return [...diagnostics].sort((left, right) => {\n if (left.line !== right.line) {\n return left.line - right.line;\n }\n\n if (left.column !== right.column) {\n return left.column - right.column;\n }\n\n return left.ruleId.localeCompare(right.ruleId);\n });\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { glob } from \"glob\";\nimport {\n lintMarkdownDocumentsAsync,\n lintMarkdownAsync,\n type MarkdownLintDiagnostic,\n type MarkdownLintOptions,\n type MarkdownLintResult,\n} from \"./lint\";\n\nconst DEFAULT_LINT_FILE_INCLUDE = [\"**/*.md\", \"**/*.markdown\", \"**/*.mdx\"] as const;\nconst DEFAULT_LINT_FILE_EXCLUDE = [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\"] as const;\n\n/**\n * File-oriented Markdown lint options for end-user configuration.\n *\n * This extends the content-level lint options with project-level targeting,\n * so consumers can decide which files should be checked and which paths should\n * be ignored.\n */\nexport interface MarkdownLintFileOptions extends MarkdownLintOptions {\n /**\n * Base directory used to resolve `include` and `exclude` patterns.\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Glob patterns for files to lint.\n * @default ['**\\/*.md', '**\\/*.markdown', '**\\/*.mdx']\n */\n include?: string[];\n\n /**\n * Glob patterns for files to exclude from linting.\n * @default ['**\\/node_modules/**', '**\\/.git/**', '**\\/dist/**']\n */\n exclude?: string[];\n\n /**\n * Alias of `exclude`.\n */\n ignore?: string[];\n}\n\n/**\n * A lint diagnostic annotated with file metadata.\n */\nexport interface MarkdownLintFileDiagnostic extends MarkdownLintDiagnostic {\n filePath: string;\n relativePath: string;\n}\n\n/**\n * Lint result for a single file.\n */\nexport interface MarkdownLintFileResult extends MarkdownLintResult {\n filePath: string;\n relativePath: string;\n skipped: boolean;\n}\n\n/**\n * Aggregated lint result for multiple files.\n */\nexport interface MarkdownLintFilesResult {\n checkedFileCount: number;\n diagnostics: MarkdownLintFileDiagnostic[];\n errorCount: number;\n files: MarkdownLintFileResult[];\n infoCount: number;\n warningCount: number;\n}\n\ninterface ResolvedMarkdownLintFileOptions {\n cwd: string;\n exclude: string[];\n include: string[];\n lintOptions: MarkdownLintOptions;\n}\n\ninterface MarkdownLintFileEntry {\n filePath: string;\n relativePath: string;\n}\n\n/**\n * Returns true if the file path is included by the configured glob filters.\n */\nexport function shouldLintMarkdownFile(\n filePath: string,\n options: MarkdownLintFileOptions = {},\n): boolean {\n const resolvedOptions = resolveMarkdownLintFileOptions(options);\n return shouldLintAbsoluteFile(path.resolve(resolvedOptions.cwd, filePath), resolvedOptions);\n}\n\n/**\n * Lints a single Markdown file using project-style include/exclude settings.\n *\n * If the file is filtered out by `include` / `exclude`, the returned result is\n * marked as `skipped` and contains no diagnostics.\n */\nexport async function lintMarkdownFile(\n filePath: string,\n options: MarkdownLintFileOptions = {},\n): Promise<MarkdownLintFileResult> {\n const resolvedOptions = resolveMarkdownLintFileOptions(options);\n return lintMarkdownFileWithResolvedOptions(\n path.resolve(resolvedOptions.cwd, filePath),\n resolvedOptions,\n );\n}\n\n/**\n * Lints all Markdown files matched by the configured include/exclude patterns.\n */\nexport async function lintMarkdownFiles(\n options: MarkdownLintFileOptions = {},\n): Promise<MarkdownLintFilesResult> {\n const resolvedOptions = resolveMarkdownLintFileOptions(options);\n const matchedFiles = await collectMarkdownLintFileEntries(resolvedOptions);\n const sources = await Promise.all(\n matchedFiles.map((file) => fs.readFile(file.filePath, \"utf-8\")),\n );\n const results = await lintMarkdownDocumentsAsync(sources, resolvedOptions.lintOptions);\n\n const files = matchedFiles.map(\n (file, index): MarkdownLintFileResult => ({\n ...(results[index] ?? createEmptyLintResult()),\n filePath: file.filePath,\n relativePath: file.relativePath,\n skipped: false,\n }),\n );\n\n const diagnostics = files.flatMap((fileResult) =>\n fileResult.diagnostics.map(\n (diagnostic): MarkdownLintFileDiagnostic => ({\n ...diagnostic,\n filePath: fileResult.filePath,\n relativePath: fileResult.relativePath,\n }),\n ),\n );\n\n return {\n checkedFileCount: files.length,\n diagnostics,\n errorCount: files.reduce((count, fileResult) => count + fileResult.errorCount, 0),\n files,\n infoCount: files.reduce((count, fileResult) => count + fileResult.infoCount, 0),\n warningCount: files.reduce((count, fileResult) => count + fileResult.warningCount, 0),\n };\n}\n\nfunction resolveMarkdownLintFileOptions(\n options: MarkdownLintFileOptions,\n): ResolvedMarkdownLintFileOptions {\n return {\n cwd: path.resolve(options.cwd ?? process.cwd()),\n exclude: [\n ...new Set([...(options.exclude ?? DEFAULT_LINT_FILE_EXCLUDE), ...(options.ignore ?? [])]),\n ],\n include: [...new Set(options.include ?? DEFAULT_LINT_FILE_INCLUDE)],\n lintOptions: {\n dictionary: options.dictionary,\n languages: options.languages,\n rules: options.rules,\n },\n };\n}\n\nasync function lintMarkdownFileWithResolvedOptions(\n filePath: string,\n options: ResolvedMarkdownLintFileOptions,\n): Promise<MarkdownLintFileResult> {\n const absoluteFilePath = path.resolve(filePath);\n const relativePath = normalizePath(path.relative(options.cwd, absoluteFilePath));\n\n if (!shouldLintAbsoluteFile(absoluteFilePath, options)) {\n return {\n ...createEmptyLintResult(),\n filePath: absoluteFilePath,\n relativePath,\n skipped: true,\n };\n }\n\n const source = await fs.readFile(absoluteFilePath, \"utf-8\");\n const result = await lintMarkdownAsync(source, options.lintOptions);\n\n return {\n ...result,\n filePath: absoluteFilePath,\n relativePath,\n skipped: false,\n };\n}\n\nasync function collectMarkdownLintFileEntries(\n options: ResolvedMarkdownLintFileOptions,\n): Promise<MarkdownLintFileEntry[]> {\n const files = new Map<string, MarkdownLintFileEntry>();\n\n for (const pattern of options.include) {\n const matches = await glob(pattern, {\n absolute: true,\n cwd: options.cwd,\n ignore: options.exclude,\n nodir: true,\n });\n\n for (const filePath of matches) {\n const absoluteFilePath = path.resolve(filePath);\n if (shouldLintAbsoluteFile(absoluteFilePath, options)) {\n files.set(absoluteFilePath, {\n filePath: absoluteFilePath,\n relativePath: normalizePath(path.relative(options.cwd, absoluteFilePath)),\n });\n }\n }\n }\n\n return [...files.values()].sort((left, right) => left.filePath.localeCompare(right.filePath));\n}\n\nfunction shouldLintAbsoluteFile(\n filePath: string,\n options: ResolvedMarkdownLintFileOptions,\n): boolean {\n const absolutePath = normalizePath(path.resolve(filePath));\n const relativePath = normalizePath(path.relative(options.cwd, absolutePath));\n\n const matches = (patterns: string[]) =>\n patterns.some((pattern) => {\n const normalizedPattern = normalizePath(pattern);\n return (\n path.matchesGlob(relativePath, normalizedPattern) ||\n path.matchesGlob(absolutePath, normalizedPattern)\n );\n });\n\n return matches(options.include) && !matches(options.exclude);\n}\n\nfunction normalizePath(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n\nfunction createEmptyLintResult(): MarkdownLintResult {\n return {\n diagnostics: [],\n errorCount: 0,\n infoCount: 0,\n warningCount: 0,\n };\n}\n","/**\n * Custom JSX Runtime for Static HTML Generation\n *\n * This module provides a JSX runtime that outputs static HTML strings.\n * No React, no hydration, no client-side JavaScript - just pure HTML.\n *\n * @example\n * ```tsx\n * // tsconfig.json or vite.config.ts\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"@ox-content/vite-plugin\"\n * }\n * }\n *\n * // MyComponent.tsx\n * export function Hero({ title }: { title: string }) {\n * return (\n * <section class=\"hero\">\n * <h1>{title}</h1>\n * </section>\n * );\n * }\n * ```\n */\n\n// Self-closing tags that don't need closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n// Attributes that should be rendered as boolean\nconst BOOLEAN_ATTRS = new Set([\n \"allowfullscreen\",\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\",\n]);\n\n/**\n * Escapes HTML special characters to prevent XSS.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n\n/**\n * Converts a camelCase attribute name to kebab-case for HTML.\n * Special handling for data-* and aria-* attributes.\n */\nfunction toHtmlAttr(name: string): string {\n // className -> class\n if (name === \"className\") return \"class\";\n // htmlFor -> for\n if (name === \"htmlFor\") return \"for\";\n // Keep data-* and aria-* as-is\n if (name.startsWith(\"data\") || name.startsWith(\"aria\")) {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n return name;\n}\n\n/**\n * Renders an attribute value to a string.\n */\nfunction renderAttr(name: string, value: unknown): string {\n const htmlName = toHtmlAttr(name);\n\n // Skip undefined, null, and false values\n if (value === undefined || value === null || value === false) {\n return \"\";\n }\n\n // Boolean attributes\n if (BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}` : \"\";\n }\n\n // Style object to string\n if (name === \"style\" && typeof value === \"object\") {\n const styleStr = Object.entries(value as Record<string, string | number>)\n .map(([k, v]) => {\n const prop = k.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return `${prop}:${v}`;\n })\n .join(\";\");\n return ` style=\"${escapeHtml(styleStr)}\"`;\n }\n\n // Regular attribute\n return ` ${htmlName}=\"${escapeHtml(String(value as string | number | boolean))}\"`;\n}\n\n/**\n * JSX element type - either a string (intrinsic) or a function component.\n */\nexport type JSXElementType = string | ((props: Record<string, unknown>) => JSXNode);\n\n/**\n * Valid JSX child types.\n */\nexport type JSXChild = string | number | boolean | null | undefined | JSXNode | JSXChild[];\n\n/**\n * JSX node - the result of JSX expressions.\n */\nexport interface JSXNode {\n __html: string;\n}\n\n/**\n * Props with children.\n */\nexport interface JSXProps {\n children?: JSXChild;\n [key: string]: unknown;\n}\n\n/**\n * Renders children to HTML string.\n */\nfunction renderChildren(children: JSXChild): string {\n if (children === null || children === undefined || children === false) {\n return \"\";\n }\n\n if (children === true) {\n return \"\";\n }\n\n if (typeof children === \"string\") {\n return escapeHtml(children);\n }\n\n if (typeof children === \"number\") {\n return String(children);\n }\n\n if (Array.isArray(children)) {\n return children.map(renderChildren).join(\"\");\n }\n\n if (typeof children === \"object\" && \"__html\" in children) {\n return children.__html;\n }\n\n return \"\";\n}\n\n/**\n * Creates a JSX element.\n * This is the core function called by the JSX transform.\n */\nexport function jsx(type: JSXElementType, props: JSXProps, _key?: string): JSXNode {\n const { children, ...restProps } = props;\n\n // Function component\n if (typeof type === \"function\") {\n return type({ ...restProps, children });\n }\n\n // Intrinsic element (HTML tag)\n const tag = type;\n let html = `<${tag}`;\n\n // Render attributes\n for (const [name, value] of Object.entries(restProps)) {\n // Skip internal props\n if (name === \"key\" || name === \"ref\") continue;\n html += renderAttr(name, value);\n }\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tag)) {\n html += \" />\";\n return { __html: html };\n }\n\n html += \">\";\n\n // Render children\n if (children !== undefined) {\n html += renderChildren(children);\n }\n\n html += `</${tag}>`;\n\n return { __html: html };\n}\n\n/**\n * Creates a JSX element with static children.\n * Called by the JSX transform for elements with multiple children.\n */\nexport function jsxs(type: JSXElementType, props: JSXProps, key?: string): JSXNode {\n return jsx(type, props, key);\n}\n\n/**\n * Fragment component - renders children without a wrapper element.\n */\nexport function Fragment({ children }: { children?: JSXChild }): JSXNode {\n return { __html: renderChildren(children) };\n}\n\n/**\n * Renders a JSX node to an HTML string.\n */\nexport function renderToString(node: JSXNode): string {\n return node.__html;\n}\n\n/**\n * Creates raw HTML without escaping.\n * Use with caution - only for trusted content.\n *\n * @example\n * ```tsx\n * <div>{raw('<strong>Bold</strong>')}</div>\n * ```\n */\nexport function raw(html: string): JSXNode {\n return { __html: html };\n}\n\n/**\n * Conditionally renders content.\n *\n * @example\n * ```tsx\n * {when(isLoggedIn, <UserMenu />)}\n * ```\n */\nexport function when(condition: boolean, content: JSXNode): JSXNode {\n return condition ? content : { __html: \"\" };\n}\n\n/**\n * Maps over an array and renders each item.\n *\n * @example\n * ```tsx\n * {each(items, (item) => <li>{item.name}</li>)}\n * ```\n */\nexport function each<T>(items: T[], render: (item: T, index: number) => JSXNode): JSXNode {\n const html = items.map((item, i) => render(item, i).__html).join(\"\");\n return { __html: html };\n}\n\n// Default export for convenience\nexport default {\n jsx,\n jsxs,\n Fragment,\n renderToString,\n raw,\n when,\n each,\n};\n","/**\n * Page Context for Static HTML Generation\n *\n * Provides a way to access page props (frontmatter, content, etc.)\n * from theme components during static rendering.\n *\n * @example\n * ```tsx\n * // theme/Layout.tsx\n * import { usePageProps, PageProps } from '@ox-content/vite-plugin';\n *\n * export function Layout({ children }: { children: JSX.Element }) {\n * const page = usePageProps<MyPageProps>();\n * return (\n * <html>\n * <head>\n * <title>{page.title}</title>\n * </head>\n * <body>\n * <header>{page.title}</header>\n * <main>{children}</main>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\n\nimport type { TocEntry } from \"./types\";\n\n/**\n * Base page props available for all pages.\n */\nexport interface BasePageProps {\n /** Page title from frontmatter or first heading */\n title: string;\n /** Page description from frontmatter */\n description?: string;\n /** Rendered HTML content */\n html: string;\n /** Table of contents entries */\n toc: TocEntry[];\n /** Last git commit timestamp in milliseconds */\n lastUpdated?: number;\n /** Source file path (relative to docs root) */\n path: string;\n /** Output URL path */\n url: string;\n /** Raw frontmatter object */\n frontmatter: Record<string, unknown>;\n /** Layout name from frontmatter */\n layout?: string;\n}\n\n/**\n * Extended page props with custom frontmatter.\n */\nexport type PageProps<T extends Record<string, unknown> = Record<string, unknown>> =\n BasePageProps & {\n /** Custom frontmatter fields */\n frontmatter: T & Record<string, unknown>;\n };\n\n/**\n * Site-wide configuration available in context.\n */\nexport interface SiteConfig {\n /** Site name */\n name: string;\n /** Base URL path */\n base: string;\n /** All pages in the site */\n pages: BasePageProps[];\n /** Navigation groups */\n nav: NavGroup[];\n}\n\n/**\n * Navigation group.\n */\nexport interface NavGroup {\n title: string;\n items: NavItem[];\n}\n\n/**\n * Navigation item.\n */\nexport interface NavItem {\n title: string;\n path: string;\n href: string;\n}\n\n/**\n * Complete render context.\n */\nexport interface RenderContext<T extends Record<string, unknown> = Record<string, unknown>> {\n /** Current page props */\n page: PageProps<T>;\n /** Site configuration */\n site: SiteConfig;\n}\n\n// Internal context storage (set during render)\nlet currentContext: RenderContext | null = null;\n\n/**\n * Sets the current render context.\n * Called internally during page rendering.\n * @internal\n */\nexport function setRenderContext(ctx: RenderContext): void {\n currentContext = ctx;\n}\n\n/**\n * Clears the current render context.\n * Called internally after page rendering.\n * @internal\n */\nexport function clearRenderContext(): void {\n currentContext = null;\n}\n\n/**\n * Gets the current page props.\n *\n * @returns The current page props\n * @throws Error if called outside of a render context\n *\n * @example\n * ```tsx\n * function PageTitle() {\n * const page = usePageProps();\n * return <h1>{page.title}</h1>;\n * }\n * ```\n */\nexport function usePageProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): PageProps<T> {\n if (!currentContext) {\n throw new Error(\n \"[ox-content] usePageProps() must be called during page rendering. \" +\n \"Make sure you are using it inside a theme component.\",\n );\n }\n return currentContext.page as PageProps<T>;\n}\n\n/**\n * Gets the site configuration.\n *\n * @returns The site configuration\n * @throws Error if called outside of a render context\n *\n * @example\n * ```tsx\n * function SiteHeader() {\n * const site = useSiteConfig();\n * return <header>{site.name}</header>;\n * }\n * ```\n */\nexport function useSiteConfig(): SiteConfig {\n if (!currentContext) {\n throw new Error(\n \"[ox-content] useSiteConfig() must be called during page rendering. \" +\n \"Make sure you are using it inside a theme component.\",\n );\n }\n return currentContext.site;\n}\n\n/**\n * Gets the full render context.\n *\n * @returns The complete render context\n * @throws Error if called outside of a render context\n *\n * @example\n * ```tsx\n * function Layout({ children }) {\n * const ctx = useRenderContext();\n * return (\n * <html>\n * <head><title>{ctx.page.title} - {ctx.site.name}</title></head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n * ```\n */\nexport function useRenderContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): RenderContext<T> {\n if (!currentContext) {\n throw new Error(\n \"[ox-content] useRenderContext() must be called during page rendering. \" +\n \"Make sure you are using it inside a theme component.\",\n );\n }\n return currentContext as RenderContext<T>;\n}\n\n/**\n * Gets the navigation groups.\n *\n * @example\n * ```tsx\n * function Sidebar() {\n * const nav = useNav();\n * return (\n * <nav>\n * {each(nav, (group) => (\n * <div>\n * <h3>{group.title}</h3>\n * <ul>\n * {each(group.items, (item) => (\n * <li><a href={item.href}>{item.title}</a></li>\n * ))}\n * </ul>\n * </div>\n * ))}\n * </nav>\n * );\n * }\n * ```\n */\nexport function useNav(): NavGroup[] {\n return useSiteConfig().nav;\n}\n\n/**\n * Checks if the given path is the current page.\n *\n * @example\n * ```tsx\n * function NavLink({ href, children }) {\n * const isActive = useIsActive(href);\n * return <a href={href} class={isActive ? 'active' : ''}>{children}</a>;\n * }\n * ```\n */\nexport function useIsActive(path: string): boolean {\n const page = usePageProps();\n return page.path === path || page.url === path;\n}\n\n// Type generation helpers\n\n/**\n * Schema for frontmatter type generation.\n */\nexport interface FrontmatterSchema {\n /** Field name */\n name: string;\n /** TypeScript type */\n type: string;\n /** Whether the field is optional */\n optional: boolean;\n /** JSDoc description */\n description?: string;\n}\n\n/**\n * Infers TypeScript types from frontmatter values.\n */\nexport function inferType(value: unknown): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (Array.isArray(value)) {\n if (value.length === 0) return \"unknown[]\";\n const itemTypes = [...new Set(value.map(inferType))];\n if (itemTypes.length === 1) return `${itemTypes[0]}[]`;\n return `(${itemTypes.join(\" | \")})[]`;\n }\n if (typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return \"Record<string, unknown>\";\n const props = entries.map(([k, v]) => `${k}: ${inferType(v)}`).join(\"; \");\n return `{ ${props} }`;\n }\n return \"unknown\";\n}\n\n/**\n * Generates TypeScript interface from frontmatter samples.\n */\nexport function generateFrontmatterTypes(\n samples: Record<string, unknown>[],\n interfaceName = \"PageFrontmatter\",\n): string {\n // Collect all fields and their types across all samples\n const fields = new Map<string, { types: Set<string>; count: number }>();\n\n for (const sample of samples) {\n for (const [key, value] of Object.entries(sample)) {\n const existing = fields.get(key) ?? { types: new Set(), count: 0 };\n existing.types.add(inferType(value));\n existing.count++;\n fields.set(key, existing);\n }\n }\n\n // Generate interface\n const lines: string[] = [\n \"/**\",\n \" * Auto-generated frontmatter type based on your pages.\",\n \" * DO NOT EDIT - this file is generated by ox-content.\",\n \" */\",\n \"\",\n `export interface ${interfaceName} {`,\n ];\n\n for (const [name, { types, count }] of fields) {\n const isOptional = count < samples.length;\n const typeStr = [...types].join(\" | \");\n const optionalMark = isOptional ? \"?\" : \"\";\n lines.push(` ${name}${optionalMark}: ${typeStr};`);\n }\n\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\n `export type PageProps = import('@ox-content/vite-plugin').PageProps<${interfaceName}>;`,\n );\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n","/**\n * Theme Renderer for Static HTML Generation\n *\n * Renders JSX theme components to static HTML strings.\n * No client-side JavaScript is included by default.\n */\n\nimport { renderToString, raw, type JSXNode } from \"./jsx-runtime\";\nimport {\n setRenderContext,\n clearRenderContext,\n generateFrontmatterTypes,\n type RenderContext,\n type PageProps,\n type SiteConfig,\n type NavGroup,\n} from \"./page-context\";\nimport type { TocEntry } from \"./types\";\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Theme component type.\n */\nexport type ThemeComponent = (props: ThemeProps) => JSXNode;\n\n/**\n * Props passed to the theme component.\n */\nexport interface ThemeProps {\n /** Rendered page content as JSX */\n children: JSXNode;\n}\n\n/**\n * Page data for rendering.\n */\nexport interface PageData {\n /** Page title */\n title: string;\n /** Page description */\n description?: string;\n /** Rendered HTML content */\n html: string;\n /** Table of contents */\n toc: TocEntry[];\n /** Last git commit timestamp in milliseconds */\n lastUpdated?: number;\n /** Source file path */\n path: string;\n /** Output URL path */\n url: string;\n /** Frontmatter */\n frontmatter: Record<string, unknown>;\n /** Layout name */\n layout?: string;\n}\n\n/**\n * Theme render options.\n */\nexport interface ThemeRenderOptions {\n /** Theme component to use */\n theme: ThemeComponent;\n /** Site name */\n siteName: string;\n /** Base URL path */\n base: string;\n /** Navigation groups */\n nav: NavGroup[];\n /** All pages (for site context) */\n pages: PageData[];\n /** Output directory for type definitions */\n typesOutDir?: string;\n}\n\n/**\n * Renders a page using the theme component.\n *\n * @param page - Page data to render\n * @param options - Theme render options\n * @returns Rendered HTML string\n */\nexport function renderPage(page: PageData, options: ThemeRenderOptions): string {\n const { theme, siteName, base, nav, pages } = options;\n\n // Build page props\n const pageProps: PageProps = {\n title: page.title,\n description: page.description,\n html: page.html,\n toc: page.toc,\n lastUpdated: page.lastUpdated,\n path: page.path,\n url: page.url,\n frontmatter: page.frontmatter,\n layout: page.layout,\n };\n\n // Build site config\n const siteConfig: SiteConfig = {\n name: siteName,\n base,\n nav,\n pages: pages.map((p) => ({\n title: p.title,\n description: p.description,\n html: p.html,\n toc: p.toc,\n lastUpdated: p.lastUpdated,\n path: p.path,\n url: p.url,\n frontmatter: p.frontmatter,\n layout: p.layout,\n })),\n };\n\n // Set render context\n const context: RenderContext = {\n page: pageProps,\n site: siteConfig,\n };\n\n setRenderContext(context);\n\n try {\n // Render theme with page content\n const contentNode = raw(page.html);\n const result = theme({ children: contentNode });\n\n // Get HTML string\n const html = renderToString(result);\n\n // Add doctype if not present\n if (!html.trimStart().toLowerCase().startsWith(\"<!doctype\")) {\n return `<!DOCTYPE html>\\n${html}`;\n }\n\n return html;\n } finally {\n clearRenderContext();\n }\n}\n\n/**\n * Renders all pages and generates type definitions.\n *\n * @param pages - All pages to render\n * @param options - Theme render options\n * @returns Map of output paths to rendered HTML\n */\nexport async function renderAllPages(\n pages: PageData[],\n options: ThemeRenderOptions,\n): Promise<Map<string, string>> {\n const results = new Map<string, string>();\n\n // Render each page\n for (const page of pages) {\n const html = renderPage(page, { ...options, pages });\n results.set(page.url, html);\n }\n\n // Generate type definitions if output directory is specified\n if (options.typesOutDir) {\n await generateTypes(pages, options.typesOutDir);\n }\n\n return results;\n}\n\n/**\n * Generates TypeScript type definitions from page frontmatter.\n *\n * @param pages - All pages\n * @param outDir - Output directory for types\n */\nexport async function generateTypes(pages: PageData[], outDir: string): Promise<void> {\n // Collect all frontmatter samples\n const samples = pages.map((p) => p.frontmatter);\n\n // Generate types\n const types = generateFrontmatterTypes(samples);\n\n // Write to file\n const typesPath = join(outDir, \"page-props.d.ts\");\n await mkdir(dirname(typesPath), { recursive: true });\n await writeFile(typesPath, types, \"utf-8\");\n}\n\n/**\n * Default theme component.\n * A minimal theme that renders page content with basic styling.\n */\nexport function DefaultTheme({ children }: ThemeProps): JSXNode {\n // Use hooks inside the component\n const { usePageProps, useSiteConfig } = require(\"./page-context\");\n const page = usePageProps();\n const site = useSiteConfig();\n\n return {\n __html: `<!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(page.title)} - ${escapeHtml(site.name)}</title>\n ${page.description ? `<meta name=\"description\" content=\"${escapeHtml(page.description)}\">` : \"\"}\n <style>\n :root {\n --octc-color-primary: #4f6fae;\n --octc-color-text: #131a30;\n --octc-color-bg: #ffffff;\n --octc-color-bg-alt: #f5f7fb;\n --octc-color-text-muted: #4f607b;\n --octc-color-border: #d2dbea;\n }\n body {\n font-family: \"IBM Plex Sans\", \"Avenir Next\", \"Segoe UI Variable\", \"Segoe UI\", sans-serif;\n line-height: 1.7;\n color: var(--octc-color-text);\n background: var(--octc-color-bg);\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n }\n a { color: var(--octc-color-primary); }\n </style>\n</head>\n<body>\n <header>\n <h1>${escapeHtml(site.name)}</h1>\n </header>\n <main>\n ${children.__html}\n </main>\n</body>\n</html>`,\n };\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\n/**\n * Creates a theme with layout switching support.\n *\n * @example\n * ```tsx\n * import { createTheme } from '@ox-content/vite-plugin';\n * import { DefaultLayout } from './layouts/Default';\n * import { EntryLayout } from './layouts/Entry';\n *\n * export default createTheme({\n * layouts: {\n * default: DefaultLayout,\n * entry: EntryLayout,\n * },\n * });\n * ```\n */\nexport function createTheme(config: {\n layouts: Record<string, ThemeComponent>;\n defaultLayout?: string;\n}): ThemeComponent {\n const { layouts, defaultLayout = \"default\" } = config;\n\n return function ThemeWithLayouts({ children }: ThemeProps): JSXNode {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { usePageProps } = require(\"./page-context\");\n const page = usePageProps();\n\n // Get layout from frontmatter or use default\n const layoutName = page.layout ?? defaultLayout;\n const Layout = layouts[layoutName] ?? layouts[defaultLayout];\n\n if (!Layout) {\n throw new Error(\n `[ox-content] Layout \"${layoutName}\" not found. ` +\n `Available layouts: ${Object.keys(layouts).join(\", \")}`,\n );\n }\n\n return Layout({ children });\n };\n}\n","/**\n * Vite Plugin for Ox Content\n *\n * Uses Vite's Environment API for SSG-focused Markdown processing.\n * Provides separate environments for client and server rendering.\n */\n\nimport * as path from \"path\";\nimport type { Plugin, ViteDevServer, ResolvedConfig } from \"vite\";\nimport { createMarkdownEnvironment } from \"./environment\";\nimport { transformMarkdown } from \"./transform\";\nimport { extractDocs, generateMarkdown, writeDocs, resolveDocsOptions } from \"./docs\";\nimport { buildSsg, resolveSsgOptions } from \"./ssg\";\nimport {\n resolveSearchOptions,\n buildSearchIndex,\n writeSearchIndex,\n generateSearchModule,\n} from \"./search\";\nimport { resolveOgImageOptions } from \"./og-image\";\nimport {\n createDevServerMiddleware,\n createDevServerCache,\n invalidateNavCache,\n invalidatePageCache,\n} from \"./dev-server\";\nimport { createOgViewerPlugin } from \"./og-viewer\";\nimport { resolveI18nOptions, createI18nPlugin } from \"./i18n\";\nimport { isMarkdownFilePath, normalizeMarkdownExtensions } from \"./markdown\";\nimport type { BuiltinPmOptions, OxContentOptions, ResolvedOptions } from \"./types\";\n\nexport type { OxContentOptions } from \"./types\";\nexport type { LanguageRegistration, ThemeRegistration } from \"shiki\";\nexport type {\n CodeAnnotationSyntax,\n CodeAnnotationsOptions,\n ResolvedCodeAnnotationsOptions,\n WikiLinkOptions,\n ResolvedWikiLinkOptions,\n EmojiShortcodeOptions,\n ResolvedEmojiShortcodeOptions,\n AttrsOptions,\n ResolvedAttrsOptions,\n CodeImportOptions,\n ResolvedCodeImportOptions,\n SanitizeOptions,\n ResolvedSanitizeOptions,\n EditThisPageOptions,\n ResolvedEditThisPageOptions,\n CodeBlockLintOptions,\n ResolvedCodeBlockLintOptions,\n CodeBlockTypecheckOptions,\n ResolvedCodeBlockTypecheckOptions,\n DocsTestOptions,\n ResolvedDocsTestOptions,\n DocsOptions,\n ResolvedDocsOptions,\n DocEntry,\n ParamDoc,\n ReturnDoc,\n ExtractedDocs,\n SsgOptions,\n ResolvedSsgOptions,\n SearchOptions,\n ResolvedSearchOptions,\n SearchDocument,\n SearchResult,\n // Entry page types\n HeroAction,\n HeroImage,\n HeroConfig,\n FeatureConfig,\n EntryPageConfig,\n SsgNavigationItem,\n SsgNavigationGroup,\n // i18n types\n I18nOptions,\n ResolvedI18nOptions,\n LocaleConfig,\n BuiltinEmbedOptions,\n ResolvedBuiltinEmbedOptions,\n BuiltinPmOptions,\n} from \"./types\";\n\n/**\n * Creates the Ox Content Vite plugin.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { oxContent } from '@ox-content/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * oxContent({\n * srcDir: 'content',\n * gfm: true,\n * }),\n * ],\n * });\n * ```\n */\nexport function oxContent(options: OxContentOptions = {}): Plugin[] {\n const resolvedOptions = resolveOptions(options);\n let config: ResolvedConfig | undefined;\n const getRoot = () => config?.root || process.cwd();\n\n const ssgDevCache = createDevServerCache();\n const plugins: Plugin[] = [\n createMainPlugin(resolvedOptions, (resolvedConfig) => {\n config = resolvedConfig;\n }),\n createEnvironmentPlugin(resolvedOptions),\n createDocsPlugin(resolvedOptions, getRoot),\n createSsgPlugin(resolvedOptions, getRoot, ssgDevCache),\n createSearchPlugin(resolvedOptions, getRoot),\n ];\n\n if (resolvedOptions.i18n) {\n plugins.push(createI18nPlugin(resolvedOptions));\n }\n\n if (resolvedOptions.ogViewer) {\n plugins.push(createOgViewerPlugin(resolvedOptions));\n }\n\n return plugins;\n}\n\nasync function regenerateDocs(resolvedOptions: ResolvedOptions, root: string): Promise<number> {\n const docsOptions = resolvedOptions.docs;\n if (!docsOptions || !docsOptions.enabled) {\n return 0;\n }\n\n const srcDirs = docsOptions.src.map((src) => path.resolve(root, src));\n const outDir = path.resolve(root, docsOptions.out);\n const extracted = await extractDocs(srcDirs, docsOptions);\n const generated = generateMarkdown(extracted, docsOptions);\n\n await writeDocs(generated, outDir, extracted, docsOptions);\n\n return Object.keys(generated).length;\n}\n\nfunction createMainPlugin(\n resolvedOptions: ResolvedOptions,\n setConfig: (config: ResolvedConfig) => void,\n): Plugin {\n return {\n name: \"ox-content\",\n\n configResolved: setConfig,\n\n configureServer(devServer) {\n devServer.middlewares.use(async (req, res, next) => {\n const url = req.url;\n if (!url || !isMarkdownFilePath(url, resolvedOptions.extensions)) {\n return next();\n }\n\n next();\n });\n },\n\n resolveId(id) {\n if (id.startsWith(\"virtual:ox-content/\")) {\n return \"\\0\" + id;\n }\n\n if (isMarkdownFilePath(id, resolvedOptions.extensions)) {\n return id;\n }\n\n return null;\n },\n\n async load(id) {\n if (id.startsWith(\"\\0virtual:ox-content/\")) {\n const virtualPath = id.slice(\"\\0virtual:ox-content/\".length);\n return generateVirtualModule(virtualPath, resolvedOptions);\n }\n\n return null;\n },\n\n async transform(code, id) {\n if (!isMarkdownFilePath(id, resolvedOptions.extensions)) {\n return null;\n }\n\n const result = await transformMarkdown(code, id, resolvedOptions);\n return {\n code: result.code,\n map: null,\n };\n },\n\n async handleHotUpdate({ file, server }) {\n if (!isMarkdownFilePath(file, resolvedOptions.extensions)) {\n return;\n }\n\n server.ws.send({\n type: \"custom\",\n event: \"ox-content:update\",\n data: { file },\n });\n\n const modules = server.moduleGraph.getModulesByFile(file);\n return modules ? Array.from(modules) : [];\n },\n };\n}\n\nfunction createEnvironmentPlugin(resolvedOptions: ResolvedOptions): Plugin {\n return {\n name: \"ox-content:environment\",\n\n config() {\n return {\n environments: {\n markdown: createMarkdownEnvironment(resolvedOptions),\n },\n };\n },\n };\n}\n\nfunction createDocsPlugin(resolvedOptions: ResolvedOptions, getRoot: () => string): Plugin {\n return {\n name: \"ox-content:docs\",\n\n async buildStart() {\n const docsOptions = resolvedOptions.docs;\n if (!docsOptions || !docsOptions.enabled) {\n return;\n }\n\n try {\n const count = await regenerateDocs(resolvedOptions, getRoot());\n console.log(`[ox-content] Generated ${count} documentation files to ${docsOptions.out}`);\n } catch (err) {\n console.warn(\"[ox-content] Failed to generate documentation:\", err);\n }\n },\n\n configureServer(devServer) {\n const docsOptions = resolvedOptions.docs;\n if (!docsOptions || !docsOptions.enabled) {\n return;\n }\n\n const root = getRoot();\n const srcDirs = docsOptions.src.map((src) => path.resolve(root, src));\n for (const srcDir of srcDirs) {\n devServer.watcher.add(srcDir);\n }\n\n devServer.watcher.on(\"all\", async (event, file) => {\n if (event !== \"add\" && event !== \"change\" && event !== \"unlink\") {\n return;\n }\n\n const isSourceFile = srcDirs.some(\n (srcDir) => file.startsWith(srcDir) && (file.endsWith(\".ts\") || file.endsWith(\".tsx\")),\n );\n if (!isSourceFile) {\n return;\n }\n\n try {\n await regenerateDocs(resolvedOptions, root);\n } catch {\n // Ignore errors during dev.\n }\n });\n },\n };\n}\n\nfunction createSsgPlugin(\n resolvedOptions: ResolvedOptions,\n getRoot: () => string,\n ssgDevCache: ReturnType<typeof createDevServerCache>,\n): Plugin {\n return {\n name: \"ox-content:ssg\",\n\n configureServer(devServer) {\n const ssgOptions = resolvedOptions.ssg;\n if (!ssgOptions.enabled) return;\n\n const root = getRoot();\n const srcDir = path.resolve(root, resolvedOptions.srcDir);\n devServer.middlewares.use(createDevServerMiddleware(resolvedOptions, root, ssgDevCache));\n\n devServer.watcher.on(\"add\", (file: string) => {\n notifySsgFileAddedOrRemoved(devServer, resolvedOptions, ssgDevCache, srcDir, file, \"add\");\n });\n devServer.watcher.on(\"unlink\", (file: string) => {\n notifySsgFileAddedOrRemoved(\n devServer,\n resolvedOptions,\n ssgDevCache,\n srcDir,\n file,\n \"unlink\",\n );\n });\n devServer.watcher.on(\"change\", (file: string) => {\n if (file.startsWith(srcDir) && isMarkdownFilePath(file, resolvedOptions.extensions)) {\n invalidatePageCache(ssgDevCache, file);\n }\n });\n },\n\n async closeBundle() {\n const ssgOptions = resolvedOptions.ssg;\n if (!ssgOptions.enabled) {\n return;\n }\n\n try {\n const result = await buildSsg(resolvedOptions, getRoot());\n if (result.files.length > 0) {\n console.log(`[ox-content] Generated ${result.files.length} output files`);\n }\n\n for (const error of result.errors) {\n console.warn(`[ox-content] ${error}`);\n }\n } catch (err) {\n console.error(\"[ox-content] SSG build failed:\", err);\n }\n },\n };\n}\n\nfunction notifySsgFileAddedOrRemoved(\n devServer: ViteDevServer,\n resolvedOptions: ResolvedOptions,\n ssgDevCache: ReturnType<typeof createDevServerCache>,\n srcDir: string,\n file: string,\n type: \"add\" | \"unlink\",\n): void {\n if (!file.startsWith(srcDir) || !isMarkdownFilePath(file, resolvedOptions.extensions)) {\n return;\n }\n\n invalidateNavCache(ssgDevCache);\n devServer.ws.send({\n type: \"custom\",\n event: \"ox-content:update\",\n data: { file, type },\n });\n}\n\nfunction createSearchPlugin(resolvedOptions: ResolvedOptions, getRoot: () => string): Plugin {\n let searchIndexJson = \"\";\n\n return {\n name: \"ox-content:search\",\n\n resolveId(id) {\n if (id === \"virtual:ox-content/search\") {\n return \"\\0virtual:ox-content/search\";\n }\n return null;\n },\n\n async load(id) {\n if (id !== \"\\0virtual:ox-content/search\") {\n return null;\n }\n\n const searchOptions = resolvedOptions.search;\n if (!searchOptions.enabled) {\n return \"export const search = () => []; export const searchOptions = { enabled: false }; export default { search, searchOptions };\";\n }\n\n const indexPath = resolvedOptions.base + \"search-index.json\";\n return generateSearchModule(searchOptions, indexPath);\n },\n\n async buildStart() {\n const searchOptions = resolvedOptions.search;\n if (!searchOptions.enabled) {\n return;\n }\n\n const srcDir = path.resolve(getRoot(), resolvedOptions.srcDir);\n try {\n searchIndexJson = await buildSearchIndex(\n srcDir,\n resolvedOptions.base,\n resolvedOptions.extensions,\n );\n console.log(\"[ox-content] Search index built\");\n } catch (err) {\n console.warn(\"[ox-content] Failed to build search index:\", err);\n }\n },\n\n async closeBundle() {\n const searchOptions = resolvedOptions.search;\n if (!searchOptions.enabled || !searchIndexJson) {\n return;\n }\n\n const outDir = path.resolve(getRoot(), resolvedOptions.outDir);\n try {\n await writeSearchIndex(searchIndexJson, outDir);\n console.log(\"[ox-content] Search index written to\", path.join(outDir, \"search-index.json\"));\n } catch (err) {\n console.warn(\"[ox-content] Failed to write search index:\", err);\n }\n },\n };\n}\n\n/**\n * Resolves plugin options with defaults.\n */\nfunction resolveOptions(options: OxContentOptions): ResolvedOptions {\n return {\n srcDir: options.srcDir ?? \"content\",\n outDir: options.outDir ?? \"dist\",\n base: options.base ?? \"/\",\n extensions: normalizeMarkdownExtensions(options.extensions),\n ssg: resolveSsgOptions(options.ssg),\n gfm: options.gfm ?? true,\n footnotes: options.footnotes ?? true,\n tables: options.tables ?? true,\n taskLists: options.taskLists ?? true,\n strikethrough: options.strikethrough ?? true,\n highlight: options.highlight ?? false,\n highlightTheme: options.highlightTheme ?? \"github-dark\",\n highlightLangs: options.highlightLangs ?? [],\n codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),\n wikiLinks: resolveWikiLinkOptions(options.wikiLinks, options.base ?? \"/\"),\n emojiShortcodes: resolveEmojiShortcodeOptions(options.emojiShortcodes),\n attrs: resolveAttrsOptions(options.attrs),\n codeImports: resolveCodeImportOptions(options.codeImports),\n sanitize: resolveSanitizeOptions(options.sanitize),\n editThisPage: resolveEditThisPageOptions(options.editThisPage),\n cjkEmphasis: options.cjkEmphasis ?? false,\n codeBlockLint: resolveCodeBlockLintOptions(options.codeBlockLint),\n codeBlockTypecheck: resolveCodeBlockTypecheckOptions(options.codeBlockTypecheck),\n docsTests: resolveDocsTestOptions(options.docsTests),\n mermaid: options.mermaid ?? false,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n ogImage: options.ogImage ?? false,\n ogImageOptions: resolveOgImageOptions(options.ogImageOptions),\n transformers: options.transformers ?? [],\n docs: resolveDocsOptions(options.docs),\n search: resolveSearchOptions(options.search),\n ogViewer: options.ogViewer ?? true,\n embeds: resolveBuiltinEmbedOptions(options.embeds),\n i18n: resolveI18nOptions(options.i18n),\n };\n}\n\nexport function resolveBuiltinEmbedOptions(\n options: OxContentOptions[\"embeds\"],\n): ResolvedOptions[\"embeds\"] {\n if (options === false) {\n return {\n github: false,\n openGraph: false,\n pm: false,\n spotify: false,\n stackBlitz: false,\n twitter: false,\n bluesky: false,\n webContainer: false,\n };\n }\n\n return {\n github: resolveSingleEmbedOptions(options?.github),\n openGraph: resolveSingleEmbedOptions(options?.openGraph),\n pm: resolvePmOptions(options?.pm),\n spotify: options?.spotify === true,\n stackBlitz: options?.stackBlitz === true,\n twitter: options?.twitter === true,\n bluesky: options?.bluesky === true,\n webContainer: options?.webContainer === true,\n };\n}\n\nfunction resolveSingleEmbedOptions<T extends object>(options: boolean | T | undefined): T | false {\n if (options === false) return false;\n if (options === true || options === undefined) return {} as T;\n return options;\n}\n\nfunction resolvePmOptions(\n options: boolean | BuiltinPmOptions | undefined,\n): BuiltinPmOptions | false {\n if (options === false || options === undefined) return false;\n if (options === true) return {};\n return options;\n}\n\nfunction resolveWikiLinkOptions(\n options: OxContentOptions[\"wikiLinks\"],\n baseUrl: string,\n): ResolvedOptions[\"wikiLinks\"] {\n if (!options) return { enabled: false, baseUrl };\n if (options === true) return { enabled: true, baseUrl };\n return { enabled: true, baseUrl: options.baseUrl ?? baseUrl };\n}\n\nfunction resolveEmojiShortcodeOptions(\n options: OxContentOptions[\"emojiShortcodes\"],\n): ResolvedOptions[\"emojiShortcodes\"] {\n if (!options) return { enabled: false, custom: {} };\n if (options === true) return { enabled: true, custom: {} };\n return { enabled: true, custom: options.custom ?? {} };\n}\n\nfunction resolveAttrsOptions(options: OxContentOptions[\"attrs\"]): ResolvedOptions[\"attrs\"] {\n if (!options) return { enabled: false };\n if (options === true) return { enabled: true };\n return { enabled: options.enabled ?? true };\n}\n\nfunction resolveCodeImportOptions(\n options: OxContentOptions[\"codeImports\"],\n): ResolvedOptions[\"codeImports\"] {\n if (!options) return { enabled: false };\n if (options === true) return { enabled: true };\n return { enabled: true, rootDir: options.rootDir };\n}\n\nfunction resolveSanitizeOptions(\n options: OxContentOptions[\"sanitize\"],\n): ResolvedOptions[\"sanitize\"] {\n if (!options) return { enabled: false };\n if (options === true) return { enabled: true };\n return {\n enabled: true,\n allowedTags: options.allowedTags,\n allowedAttributes: options.allowedAttributes,\n allowedUrlSchemes: options.allowedUrlSchemes,\n };\n}\n\nfunction resolveEditThisPageOptions(\n options: OxContentOptions[\"editThisPage\"],\n): ResolvedOptions[\"editThisPage\"] {\n if (!options) return { enabled: false, branch: \"main\", label: \"Edit this page\" };\n if (options === true) return { enabled: false, branch: \"main\", label: \"Edit this page\" };\n return {\n enabled: Boolean(options.repoUrl),\n repoUrl: options.repoUrl,\n branch: options.branch ?? \"main\",\n rootDir: options.rootDir,\n label: options.label ?? \"Edit this page\",\n };\n}\n\nfunction resolveCodeBlockLintOptions(\n options: OxContentOptions[\"codeBlockLint\"],\n): ResolvedOptions[\"codeBlockLint\"] {\n if (!options) {\n return { enabled: false, requireLanguage: false, trailingSpaces: true, mode: \"warn\" };\n }\n if (options === true) {\n return { enabled: true, requireLanguage: false, trailingSpaces: true, mode: \"warn\" };\n }\n return {\n enabled: true,\n languages: options.languages,\n requireLanguage: options.requireLanguage ?? false,\n trailingSpaces: options.trailingSpaces ?? true,\n mode: options.mode ?? \"warn\",\n };\n}\n\nfunction resolveCodeBlockTypecheckOptions(\n options: OxContentOptions[\"codeBlockTypecheck\"],\n): ResolvedOptions[\"codeBlockTypecheck\"] {\n if (!options) {\n return {\n enabled: false,\n languages: [\"ts\", \"tsx\"],\n requireMeta: true,\n tsgoCommand: \"tsgo\",\n mode: \"warn\",\n };\n }\n if (options === true) {\n return {\n enabled: true,\n languages: [\"ts\", \"tsx\"],\n requireMeta: true,\n tsgoCommand: \"tsgo\",\n mode: \"warn\",\n };\n }\n return {\n enabled: true,\n languages: options.languages ?? [\"ts\", \"tsx\"],\n requireMeta: options.requireMeta ?? true,\n tsgoCommand: options.tsgoCommand ?? \"tsgo\",\n mode: options.mode ?? \"warn\",\n };\n}\n\nfunction resolveDocsTestOptions(\n options: OxContentOptions[\"docsTests\"],\n): ResolvedOptions[\"docsTests\"] {\n if (!options) return { enabled: false, languages: [\"js\", \"jsx\", \"ts\", \"tsx\"], requireMeta: true };\n if (options === true) {\n return { enabled: true, languages: [\"js\", \"jsx\", \"ts\", \"tsx\"], requireMeta: true };\n }\n return {\n enabled: true,\n languages: options.languages ?? [\"js\", \"jsx\", \"ts\", \"tsx\"],\n requireMeta: options.requireMeta ?? true,\n };\n}\n\nfunction resolveCodeAnnotationsOptions(\n options: OxContentOptions[\"codeAnnotations\"],\n): ResolvedOptions[\"codeAnnotations\"] {\n if (!options) {\n return {\n enabled: false,\n notation: \"attribute\",\n metaKey: \"annotate\",\n defaultLineNumbers: false,\n };\n }\n\n if (options === true) {\n return {\n enabled: true,\n notation: \"attribute\",\n metaKey: \"annotate\",\n defaultLineNumbers: false,\n };\n }\n\n return {\n enabled: true,\n notation: options.notation ?? \"attribute\",\n metaKey: options.metaKey ?? \"annotate\",\n defaultLineNumbers: options.defaultLineNumbers ?? false,\n };\n}\n\n/**\n * Generates virtual module content.\n */\nexport function generateVirtualModule(path: string, options: ResolvedOptions): string {\n if (path === \"config\") {\n return `export default ${JSON.stringify(options)};`;\n }\n\n if (path === \"runtime\") {\n const base = normalizeRuntimeBase(options.base);\n return `\n export const base = ${JSON.stringify(base)};\n export const runtimeConfig = { base };\n\n export function isExternalUrl(value) {\n return /^(?:https?:)?\\\\/\\\\//i.test(value) || /^(?:mailto|tel):/i.test(value);\n }\n\n export function withBase(pathname = \"\") {\n const value = String(pathname);\n if (!value || value === \"/\") return base;\n if (value.startsWith(\"#\") || isExternalUrl(value)) return value;\n return base + (value.startsWith(\"/\") ? value.slice(1) : value);\n }\n\n export function withoutBase(pathname = \"\") {\n const value = String(pathname);\n if (base === \"/\" || value.startsWith(\"#\") || isExternalUrl(value)) return value;\n const bareBase = base.slice(0, -1);\n if (value === bareBase) return \"/\";\n if (value.startsWith(base)) return \"/\" + value.slice(base.length);\n return value;\n }\n\n export function useMarkdown() {\n return {\n base,\n withBase,\n withoutBase,\n render: (content) => {\n return content;\n },\n };\n }\n `;\n }\n\n return \"export default {};\";\n}\n\nfunction normalizeRuntimeBase(base: string): string {\n const trimmed = base.trim();\n if (!trimmed || trimmed === \"/\") return \"/\";\n const withLeading = trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n return withLeading.endsWith(\"/\") ? withLeading : `${withLeading}/`;\n}\n\n// Re-export types and utilities\nexport { createMarkdownEnvironment } from \"./environment\";\nexport { transformMarkdown } from \"./transform\";\nexport {\n extractCodeBlocks,\n extractDocsTests,\n lintCodeBlocks,\n typecheckCodeBlocks,\n type CodeBlockDiagnostic,\n type ExtractedCodeBlock,\n type TypecheckCodeBlockOptions,\n} from \"./code-blocks\";\nexport { extractDocs, generateMarkdown, writeDocs, resolveDocsOptions } from \"./docs\";\nexport { lintMarkdown, lintMarkdownAsync } from \"./lint\";\nexport { lintMarkdownFile, lintMarkdownFiles, shouldLintMarkdownFile } from \"./lint-files\";\nexport type {\n MarkdownLintDiagnostic,\n MarkdownLintDictionaryOptions,\n MarkdownLintLanguage,\n MarkdownLintOptions,\n MarkdownLintResult,\n MarkdownLintRuleOptions,\n MarkdownLintSeverity,\n MarkdownLintStandardDictionaryOptions,\n} from \"./lint\";\nexport type {\n MarkdownLintFileDiagnostic as MarkdownLintBatchDiagnostic,\n MarkdownLintFileDiagnostic,\n MarkdownLintFileOptions,\n MarkdownLintFileResult,\n MarkdownLintFilesResult,\n MarkdownLintFileOptions as MarkdownLintProjectOptions,\n} from \"./lint-files\";\nexport { buildSsg, resolveSsgOptions, DEFAULT_HTML_TEMPLATE } from \"./ssg\";\nexport { resolveSearchOptions, buildSearchIndex, writeSearchIndex } from \"./search\";\nexport {\n DEFAULT_MARKDOWN_EXTENSIONS,\n normalizeMarkdownExtensions,\n isMarkdownFilePath,\n stripMarkdownExtension,\n} from \"./markdown\";\nexport { defineTheme, defaultTheme, mergeThemes, resolveTheme } from \"./theme\";\nexport {\n fromVitePressConfig,\n generateVitePressMigrationConfig,\n convertVitePressSidebar,\n convertVitePressNav,\n normalizeVitePressFrontmatter,\n} from \"./vitepress\";\nexport type {\n GenerateVitePressMigrationConfigOptions,\n VitePressConfig,\n VitePressThemeConfig,\n VitePressSidebar,\n VitePressSidebarItem,\n VitePressNavItem,\n VitePressSocialLink,\n VitePressFooter,\n VitePressLogo,\n} from \"./vitepress\";\nexport type {\n ThemeConfig,\n ThemeColors,\n ThemeLayout,\n ThemeFonts,\n ThemeEntryPage,\n ThemeHeader,\n ThemeFooter,\n SocialLinks,\n ThemeEmbed,\n ResolvedThemeConfig,\n} from \"./theme\";\nexport * from \"./types\";\n\n// JSX Runtime\nexport { jsx, jsxs, Fragment, renderToString, raw, when, each } from \"./jsx-runtime\";\nexport type { JSXNode, JSXChild, JSXProps, JSXElementType } from \"./jsx-runtime\";\n\n// Page Context\nexport {\n usePageProps,\n useSiteConfig,\n useRenderContext,\n useNav,\n useIsActive,\n setRenderContext,\n clearRenderContext,\n generateFrontmatterTypes,\n inferType,\n} from \"./page-context\";\nexport type {\n BasePageProps,\n PageProps,\n SiteConfig,\n NavGroup,\n NavItem,\n RenderContext,\n FrontmatterSchema,\n} from \"./page-context\";\n\n// Theme Renderer\nexport {\n renderPage,\n renderAllPages,\n generateTypes,\n DefaultTheme,\n createTheme,\n} from \"./theme-renderer\";\nexport type { ThemeComponent, ThemeProps, PageData, ThemeRenderOptions } from \"./theme-renderer\";\n\n// Built-in Plugins (No-JS First)\nexport {\n transformTabs,\n generateTabsCSS,\n transformYouTube,\n extractVideoId,\n transformGitHub,\n fetchRepoData,\n fetchGitHubSource,\n collectGitHubRepos,\n collectGitHubSources,\n prefetchGitHubRepos,\n prefetchGitHubSources,\n parseGitHubPermalink,\n parseGitHubLineRange,\n transformOgp,\n fetchOgpData,\n collectOgpUrls,\n prefetchOgpData,\n transformMermaidStatic,\n mermaidClientScript,\n transformAllPlugins,\n} from \"./plugins\";\nexport type {\n YouTubeOptions,\n GitHubRepoData,\n GitHubSourceData,\n GitHubSourceRef,\n GitHubLineRange,\n GitHubOptions,\n OgpData,\n OgpOptions,\n MermaidOptions,\n TransformAllOptions,\n} from \"./plugins\";\n\n// Island Architecture\nexport { transformIslands, hasIslands, extractIslandInfo, generateHydrationScript } from \"./island\";\nexport type { LoadStrategy, IslandInfo, ParseIslandsResult } from \"./island\";\n\n// OG Image\nexport { resolveOgImageOptions, generateOgImages } from \"./og-image\";\nexport { resolveI18nOptions, createI18nPlugin } from \"./i18n\";\nexport type {\n OgImageOptions as OgImagePluginOptions,\n ResolvedOgImageOptions,\n OgImageTemplateProps,\n OgImageTemplateFn,\n OgImagePageEntry,\n OgImageResult,\n OgBrowserSession,\n} from \"./og-image\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["path","path","escapeHtml","path","fs","path","extractTitle","fs","path","getUrlPath","resolveSiteName","oxContent","path","fs","renderPage","extractTitle","getUrlPath","path","fs","path","fs","normalizePath","require","createEmptyLintResult","escapeHtml","path"],"sources":["../src/markdown.ts","../src/environment.ts","../src/highlight.ts","../src/plugins/index.ts","../src/plugins/mermaid-protect.ts","../src/code-blocks.ts","../src/transform.ts","../src/docs.ts","../src/og-image/renderer.ts","../src/og-image/browser.ts","../src/og-image/template.ts","../src/og-image/cache.ts","../src/og-image/index.ts","../src/island/parse.ts","../src/ssg.ts","../src/search.ts","../src/dev-server.ts","../src/og-viewer.ts","../src/i18n.ts","../src/docs-tests.ts","../src/lint.ts","../src/lint-files.ts","../src/jsx-runtime.ts","../src/page-context.ts","../src/theme-renderer.ts","../src/index.ts"],"sourcesContent":["import * as path from \"path\";\n\nexport const DEFAULT_MARKDOWN_EXTENSIONS = [\".md\", \".markdown\", \".mdx\"] as const;\n\nexport function normalizeMarkdownExtensions(extensions?: readonly string[]): string[] {\n const values = extensions?.length ? extensions : DEFAULT_MARKDOWN_EXTENSIONS;\n const seen = new Set<string>();\n const normalized: string[] = [];\n\n for (const extension of values) {\n const value = extension.startsWith(\".\") ? extension : `.${extension}`;\n const key = value.toLowerCase();\n if (!seen.has(key)) {\n seen.add(key);\n normalized.push(value);\n }\n }\n\n return normalized;\n}\n\nexport function isMarkdownFilePath(\n filePath: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): boolean {\n const pathname = filePath.split(\"?\")[0].split(\"#\")[0].toLowerCase();\n return extensions.some((extension) => pathname.endsWith(extension.toLowerCase()));\n}\n\nexport function stripMarkdownExtension(\n filePath: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): string {\n const match = [...extensions]\n .sort((left, right) => right.length - left.length)\n .find((extension) => filePath.toLowerCase().endsWith(extension.toLowerCase()));\n\n return match ? filePath.slice(0, -match.length) : filePath;\n}\n\nexport function markdownGlobPattern(srcDir: string, extensions: readonly string[]): string {\n const suffixes = extensions.map((extension) => extension.replace(/^\\./, \"\"));\n if (suffixes.length === 1) {\n return path.join(srcDir, `**/*.${suffixes[0]}`);\n }\n return path.join(srcDir, `**/*.{${suffixes.join(\",\")}}`);\n}\n","/**\n * Vite Environment API integration for Ox Content.\n *\n * Creates a dedicated environment for Markdown processing,\n * enabling SSG-style rendering with separate client/server contexts.\n */\n\nimport type { EnvironmentOptions } from \"vite\";\nimport type { ResolvedOptions } from \"./types\";\nimport { isMarkdownFilePath } from \"./markdown\";\n\n/**\n * Creates the Markdown processing environment configuration.\n *\n * This environment is used for:\n * - Server-side rendering of Markdown files\n * - Static site generation\n * - Pre-rendering at build time\n *\n * @example\n * ```ts\n * // In your vite.config.ts\n * export default defineConfig({\n * environments: {\n * markdown: createMarkdownEnvironment({\n * srcDir: 'content',\n * gfm: true,\n * }),\n * },\n * });\n * ```\n */\nexport function createMarkdownEnvironment(options: ResolvedOptions): EnvironmentOptions {\n return {\n // Consumer type for this environment\n consumer: \"server\",\n\n // Build configuration\n build: {\n // Output to a separate directory\n outDir: `${options.outDir}/.markdown`,\n\n // Emit assets for SSG\n emitAssets: true,\n\n // Create manifest for asset tracking\n manifest: true,\n\n // SSR-like externalization\n rollupOptions: {\n external: [\n // Externalize Node.js built-ins\n /^node:/,\n // Externalize native modules\n /\\.node$/,\n ],\n },\n },\n\n // Resolve configuration\n resolve: {\n // Handle Markdown-like files\n extensions: options.extensions,\n\n // Conditions for module resolution\n conditions: [\"markdown\", \"node\", \"import\"],\n\n // Don't dedupe - each environment gets its own modules\n dedupe: [],\n },\n\n // Optimize dependencies\n optimizeDeps: {\n // Include ox-content dependencies\n include: [],\n // Exclude native modules\n exclude: [\"@ox-content/napi\"],\n },\n };\n}\n\n/**\n * Environment-specific module transformer.\n *\n * This is called during the transform phase to process\n * Markdown files within the environment context.\n */\nexport interface EnvironmentTransformContext {\n /**\n * Current environment name.\n */\n environment: string;\n\n /**\n * Whether we're in development mode.\n */\n isDev: boolean;\n\n /**\n * Whether this is a server-side render.\n */\n isSSR: boolean;\n\n /**\n * The resolved Vite config.\n */\n config: unknown;\n}\n\n/**\n * Creates environment-aware transform options.\n */\nexport function createTransformOptions(\n ctx: EnvironmentTransformContext,\n options: ResolvedOptions,\n): ResolvedOptions {\n return {\n ...options,\n // Adjust options based on environment\n highlight: ctx.isSSR ? options.highlight : false,\n ogImage: ctx.isSSR ? options.ogImage : false,\n };\n}\n\n/**\n * Runs pre-render for SSG.\n *\n * This function is called during build to pre-render all Markdown files.\n */\nexport async function prerender(\n files: string[],\n _options: ResolvedOptions,\n): Promise<Map<string, string>> {\n const results = new Map<string, string>();\n\n for (const file of files) {\n // In production, this would use the Ox Content parser\n // For now, we just mark the file as needing processing\n results.set(file, `/* Pre-rendered: ${file} */`);\n }\n\n return results;\n}\n\n/**\n * Environment plugin factory.\n *\n * Creates plugins specific to the Markdown environment.\n */\nexport function createEnvironmentPlugins(options: ResolvedOptions) {\n return [\n {\n name: \"ox-content:markdown-env\",\n\n // Only apply to markdown environment\n applyToEnvironment(name: string) {\n return name === \"markdown\";\n },\n\n // Transform within the environment\n transform(code: string, id: string) {\n if (!isMarkdownFilePath(id, options.extensions)) {\n return null;\n }\n\n // Environment-specific transformation\n return {\n code: `\n // Transformed in markdown environment\n ${code}\n `,\n };\n },\n },\n ];\n}\n","/**\n * Syntax highlighting with Shiki via rehype.\n */\n\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeStringify from \"rehype-stringify\";\nimport type { Root, Element } from \"hast\";\nimport {\n createHighlighter,\n type Highlighter,\n type BundledTheme,\n type LanguageRegistration,\n type ThemeRegistration,\n} from \"shiki\";\n\nconst BUILTIN_LANGS = [\n \"javascript\",\n \"typescript\",\n \"jsx\",\n \"tsx\",\n \"vue\",\n \"svelte\",\n \"html\",\n \"css\",\n \"scss\",\n \"json\",\n \"yaml\",\n \"markdown\",\n \"bash\",\n \"shell\",\n \"rust\",\n \"python\",\n \"go\",\n \"java\",\n \"c\",\n \"cpp\",\n \"sql\",\n \"graphql\",\n \"diff\",\n \"toml\",\n] as const;\n\n// Cache highlighters by theme + language registration set.\nconst highlighterCache = new Map<string, Promise<Highlighter>>();\n\n/**\n * Get or create the Shiki highlighter.\n */\nasync function getHighlighter(\n theme: string | ThemeRegistration,\n customLangs: LanguageRegistration[] = [],\n): Promise<Highlighter> {\n const { themeInput } = normalizeThemeInput(theme);\n const cacheKey = JSON.stringify({\n theme: themeInput,\n langs: customLangs,\n });\n\n let highlighterPromise = highlighterCache.get(cacheKey);\n if (!highlighterPromise) {\n highlighterPromise = createHighlighter({\n themes: [themeInput as BundledTheme | ThemeRegistration],\n langs: [...BUILTIN_LANGS, ...customLangs],\n });\n highlighterCache.set(cacheKey, highlighterPromise);\n }\n return highlighterPromise;\n}\n\nfunction normalizeThemeInput(theme: string | ThemeRegistration): {\n themeInput: string | ThemeRegistration;\n themeName: string;\n} {\n if (typeof theme === \"string\") {\n return {\n themeInput: theme,\n themeName: theme,\n };\n }\n\n const themeName = theme.name || \"ox-content-custom-theme\";\n return {\n themeInput: theme.name ? theme : { ...theme, name: themeName },\n themeName,\n };\n}\n\n/**\n * Rehype plugin for syntax highlighting with Shiki.\n */\nfunction rehypeShikiHighlight(options: {\n theme: string | ThemeRegistration;\n langs?: LanguageRegistration[];\n}) {\n const { theme, langs } = options;\n\n return async (tree: Root) => {\n const { themeName } = normalizeThemeInput(theme);\n const highlighter = await getHighlighter(theme, langs);\n\n const highlightBlockCode = (codeElement: Element): Element | null => {\n let lang = \"text\";\n const originalCodeClasses = normalizeClassName(codeElement.properties?.className);\n\n const langClass = originalCodeClasses.find((value) => value.startsWith(\"language-\"));\n if (langClass) {\n lang = langClass.replace(\"language-\", \"\");\n }\n\n const codeText = getTextContent(codeElement);\n\n try {\n const highlighted = highlighter.codeToHtml(codeText, {\n lang: lang as any,\n theme: themeName as BundledTheme,\n });\n\n const parsed = unified().use(rehypeParse, { fragment: true }).parse(highlighted);\n\n if (parsed.children[0]?.type === \"element\") {\n const highlightedPre = parsed.children[0];\n highlightedPre.properties ??= {};\n highlightedPre.properties[\"data-language\"] = lang;\n return highlightedPre;\n }\n } catch {\n // If highlighting fails, keep the original\n }\n\n return null;\n };\n\n const highlightInlineCode = (codeElement: Element): Element | null => {\n let lang = \"text\";\n const originalCodeClasses = normalizeClassName(codeElement.properties?.className);\n\n const langClass = originalCodeClasses.find((value) => value.startsWith(\"language-\"));\n if (!langClass) {\n return null;\n }\n\n lang = langClass.replace(\"language-\", \"\");\n const codeText = getTextContent(codeElement);\n\n try {\n const highlighted = highlighter.codeToHtml(codeText, {\n lang: lang as any,\n theme: themeName as BundledTheme,\n });\n\n const parsed = unified().use(rehypeParse, { fragment: true }).parse(highlighted);\n\n if (parsed.children[0]?.type === \"element\") {\n const highlightedPre = parsed.children[0];\n const highlightedCode = highlightedPre.children.find(\n (child): child is Element => child.type === \"element\" && child.tagName === \"code\",\n );\n\n if (highlightedCode) {\n highlightedCode.properties ??= {};\n const highlightedClasses = normalizeClassName(highlightedCode.properties.className);\n highlightedCode.properties.className = [\n ...new Set([...originalCodeClasses, ...highlightedClasses, \"shiki-inline\"]),\n ];\n highlightedCode.properties[\"data-language\"] = lang;\n return highlightedCode;\n }\n }\n } catch {\n // If highlighting fails, keep the original\n }\n\n return null;\n };\n\n // Find all pre > code elements\n const visit = async (node: Root | Element) => {\n if (\"children\" in node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n if (child.type === \"element\" && child.tagName === \"pre\") {\n const codeElement = child.children.find(\n (c): c is Element => c.type === \"element\" && c.tagName === \"code\",\n );\n\n if (codeElement) {\n const highlightedPre = highlightBlockCode(codeElement);\n if (highlightedPre) {\n node.children[i] = highlightedPre;\n }\n }\n } else if (child.type === \"element\" && child.tagName === \"code\") {\n const highlightedCode = highlightInlineCode(child);\n if (highlightedCode) {\n node.children[i] = highlightedCode;\n }\n } else if (child.type === \"element\") {\n await visit(child);\n }\n }\n }\n };\n\n await visit(tree);\n };\n}\n\n/**\n * Extract text content from a hast node.\n */\nfunction getTextContent(node: Element | Root): string {\n let text = \"\";\n\n if (\"children\" in node) {\n for (const child of node.children) {\n if (child.type === \"text\") {\n text += child.value;\n } else if (child.type === \"element\") {\n text += getTextContent(child);\n }\n }\n }\n\n return text;\n}\n\nfunction normalizeClassName(className: unknown): string[] {\n if (Array.isArray(className)) {\n return className.filter((value): value is string => typeof value === \"string\");\n }\n\n if (typeof className === \"string\" && className) {\n return className.split(/\\s+/).filter(Boolean);\n }\n\n return [];\n}\n\n/**\n * Apply syntax highlighting to HTML using Shiki.\n */\nexport async function highlightCode(\n html: string,\n theme: string | ThemeRegistration = \"github-dark\",\n langs: LanguageRegistration[] = [],\n): Promise<string> {\n const result = await unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeShikiHighlight, { theme, langs })\n .use(rehypeStringify)\n .process(html);\n\n return String(result);\n}\n","/**\n * ox-content Built-in Plugins\n *\n * All plugins are designed with No-JavaScript-First principle.\n * They generate static HTML at build time and require no client-side JS.\n */\n\nimport type { GitHubOptions } from \"./github\";\nimport type { MediaEmbedOptions } from \"./media\";\nimport type { OgpOptions } from \"./ogp\";\nimport type { PmOptions } from \"./pm\";\n\nexport {\n transformTabs,\n generateTabsCSS,\n resetTabGroupCounter,\n getTabGroupCounter,\n setTabGroupCounter,\n} from \"./tabs\";\n\nexport { transformPm, type PmOptions } from \"./pm\";\n\nexport { transformYouTube, extractVideoId, type YouTubeOptions } from \"./youtube\";\nexport { transformMediaEmbeds, type MediaEmbedOptions } from \"./media\";\n\nexport {\n transformGitHub,\n fetchRepoData,\n fetchGitHubSource,\n collectGitHubRepos,\n collectGitHubSources,\n prefetchGitHubRepos,\n prefetchGitHubSources,\n parseGitHubPermalink,\n parseGitHubLineRange,\n type GitHubRepoData,\n type GitHubSourceData,\n type GitHubSourceRef,\n type GitHubLineRange,\n type GitHubOptions,\n} from \"./github\";\n\nexport {\n transformOgp,\n fetchOgpData,\n collectOgpUrls,\n prefetchOgpData,\n type OgpData,\n type OgpOptions,\n} from \"./ogp\";\n\nexport { transformMermaidStatic, mermaidClientScript, type MermaidOptions } from \"./mermaid\";\n\n/**\n * Transform all plugin components in HTML.\n * Call this during SSG build to process all plugins at once.\n */\nexport interface TransformAllOptions {\n tabs?: boolean;\n /**\n * Expand `<pm>` package-manager blocks into install tabs. Pass an object to\n * opt in to synced groups (`{ sync: true }`); syncing is off by default.\n * @default false\n */\n pm?: boolean | PmOptions;\n youtube?: boolean;\n github?: boolean | GitHubOptions;\n ogp?: boolean | OgpOptions;\n openGraph?: boolean | OgpOptions;\n mermaid?: boolean;\n githubToken?: string;\n spotify?: boolean;\n stackBlitz?: boolean;\n twitter?: boolean;\n bluesky?: boolean;\n webContainer?: boolean;\n}\n\n/**\n * Transform all enabled plugins in HTML content.\n */\nexport async function transformAllPlugins(\n html: string,\n options: TransformAllOptions = {},\n): Promise<string> {\n const {\n tabs = true,\n pm = false,\n youtube = true,\n github = true,\n ogp,\n openGraph,\n mermaid = true,\n githubToken,\n spotify = false,\n stackBlitz = false,\n twitter = false,\n bluesky = false,\n webContainer = false,\n } = options;\n\n let result = html;\n const ogpOptions = openGraph ?? ogp ?? true;\n\n // Order matters: process in dependency order\n\n // 1. Tabs (no external dependencies)\n if (tabs) {\n const { transformTabs } = await import(\"./tabs\");\n result = await transformTabs(result);\n }\n\n // 1b. Package-manager tabs (no external dependencies). Shares the tab-group\n // counter with the tabs transform, so it runs right after it. Syncing is\n // opt-in via `{ pm: { sync: true } }` and off by default.\n if (pm) {\n const { transformPm } = await import(\"./pm\");\n result = await transformPm(result, typeof pm === \"object\" ? pm : {});\n }\n\n // 2. YouTube (no external dependencies)\n if (youtube) {\n const { transformYouTube } = await import(\"./youtube\");\n result = await transformYouTube(result);\n }\n\n // 3. GitHub (requires API calls)\n if (github !== false) {\n const { transformGitHub } = await import(\"./github\");\n const options = typeof github === \"object\" ? github : {};\n result = await transformGitHub(result, undefined, { token: githubToken, ...options });\n }\n\n // 4. OGP (requires fetch calls)\n if (ogpOptions !== false) {\n const { transformOgp } = await import(\"./ogp\");\n result = await transformOgp(\n result,\n undefined,\n typeof ogpOptions === \"object\" ? ogpOptions : {},\n );\n }\n\n const mediaOptions = { spotify, stackBlitz, twitter, bluesky, webContainer };\n if (Object.values(mediaOptions).some(Boolean)) {\n const { transformMediaEmbeds } = await import(\"./media\");\n result = await transformMediaEmbeds(result, mediaOptions);\n }\n\n // 5. Mermaid (requires mermaid library)\n if (mermaid) {\n const { transformMermaidStatic } = await import(\"./mermaid\");\n result = await transformMermaidStatic(result);\n }\n\n return result;\n}\n\n/**\n * Transform built-in embed components in HTML content.\n */\nexport async function transformBuiltinEmbeds(\n html: string,\n options: {\n github: GitHubOptions | false;\n openGraph: OgpOptions | false;\n pm?: PmOptions | false;\n spotify?: boolean;\n stackBlitz?: boolean;\n twitter?: boolean;\n bluesky?: boolean;\n webContainer?: boolean;\n },\n): Promise<string> {\n let result = html;\n\n if (options.github) {\n const { transformGitHub } = await import(\"./github\");\n result = await transformGitHub(result, undefined, {\n token: process.env.GITHUB_TOKEN,\n ...options.github,\n });\n }\n\n if (options.openGraph) {\n const { transformOgp } = await import(\"./ogp\");\n result = await transformOgp(result, undefined, options.openGraph);\n }\n\n if (options.pm) {\n const { transformPm } = await import(\"./pm\");\n result = await transformPm(result, typeof options.pm === \"object\" ? options.pm : {});\n }\n\n const mediaOptions: MediaEmbedOptions = {\n spotify: options.spotify,\n stackBlitz: options.stackBlitz,\n twitter: options.twitter,\n bluesky: options.bluesky,\n webContainer: options.webContainer,\n };\n if (Object.values(mediaOptions).some(Boolean)) {\n const { transformMediaEmbeds } = await import(\"./media\");\n result = await transformMediaEmbeds(result, mediaOptions);\n }\n\n return result;\n}\n","/**\n * Protects mermaid SVG content from rehype HTML5 parser corruption.\n *\n * rehypeParse + rehypeStringify converts `<br />` in SVG foreignObject\n * to `<br></br>`, which HTML5 interprets as 2 <br> elements.\n * Each rehype pass doubles them: 1 → 2 → 4 → 8 → 16.\n *\n * This module extracts ox-mermaid SVG blocks into placeholders before\n * rehype processing and restores them after.\n */\n\nexport interface MermaidSvgProtection {\n html: string;\n svgs: Map<string, string>;\n}\n\n/**\n * Extract `<div class=\"ox-mermaid\">...</div>` blocks and replace\n * with HTML comment placeholders that rehype will preserve.\n */\nexport function protectMermaidSvgs(html: string): MermaidSvgProtection {\n const svgs = new Map<string, string>();\n let result = html;\n let idx = 0;\n\n while (true) {\n const marker = `<div class=\"ox-mermaid\">`;\n const start = result.indexOf(marker, idx);\n if (start === -1) break;\n\n // Find the matching </div> by counting nested divs\n let depth = 0;\n let pos = start;\n let endPos = -1;\n\n while (pos < result.length) {\n const openIdx = result.indexOf(\"<div\", pos);\n const closeIdx = result.indexOf(\"</div>\", pos);\n if (closeIdx === -1) break;\n\n if (openIdx !== -1 && openIdx < closeIdx) {\n depth++;\n pos = openIdx + 4;\n } else {\n depth--;\n if (depth === 0) {\n endPos = closeIdx + 6;\n break;\n }\n pos = closeIdx + 6;\n }\n }\n\n if (endPos === -1) break;\n\n const svgContent = result.substring(start, endPos);\n const placeholder = `<!--ox-mermaid-${svgs.size}-->`;\n svgs.set(placeholder, svgContent);\n result = result.substring(0, start) + placeholder + result.substring(endPos);\n idx = start + placeholder.length;\n }\n\n return { html: result, svgs };\n}\n\n/**\n * Restore protected mermaid SVG blocks from placeholders.\n */\nexport function restoreMermaidSvgs(html: string, svgs: Map<string, string>): string {\n if (svgs.size === 0) {\n return html;\n }\n // Single pass over the HTML instead of one full `String.replace` scan per\n // placeholder (O(svgs × html) → O(html)). The function replacer also avoids\n // the `$`-pattern interpretation that the string form of `replace` applies\n // to the SVG replacement content.\n return html.replace(/<!--ox-mermaid-\\d+-->/g, (placeholder) => {\n const content = svgs.get(placeholder);\n return content !== undefined ? content : placeholder;\n });\n}\n","import { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { execFile } from \"node:child_process\";\nimport { importNapiModule } from \"./napi\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface ExtractedCodeBlock {\n language: string;\n meta: string;\n code: string;\n startLine: number;\n endLine: number;\n}\n\nexport interface CodeBlockDiagnostic {\n ruleId: string;\n severity: \"error\" | \"warning\" | \"info\";\n message: string;\n line: number;\n column: number;\n endLine: number;\n endColumn: number;\n language?: string;\n}\n\nexport interface CodeBlockLintOptions {\n languages?: string[];\n requireLanguage?: boolean;\n trailingSpaces?: boolean;\n}\n\nexport interface DocsTestOptions {\n languages?: string[];\n requireMeta?: boolean;\n}\n\nexport interface TypecheckCodeBlockOptions {\n languages?: string[];\n requireMeta?: boolean;\n tsgoCommand?: string;\n}\n\nexport async function extractCodeBlocks(source: string): Promise<ExtractedCodeBlock[]> {\n const mod = await importNapiModule();\n return mod.extractCodeBlocks(source).map(normalizeBlock);\n}\n\nexport async function lintCodeBlocks(\n source: string,\n options: CodeBlockLintOptions = {},\n): Promise<CodeBlockDiagnostic[]> {\n const mod = await importNapiModule();\n return mod\n .lintCodeBlocks(source, {\n enabled: true,\n languages: options.languages,\n requireLanguage: options.requireLanguage,\n trailingSpaces: options.trailingSpaces,\n })\n .map(normalizeDiagnostic);\n}\n\nexport async function extractDocsTests(\n source: string,\n options: DocsTestOptions = {},\n): Promise<ExtractedCodeBlock[]> {\n const mod = await importNapiModule();\n return mod\n .extractDocsTests(source, {\n enabled: true,\n languages: options.languages,\n requireMeta: options.requireMeta,\n })\n .map(normalizeBlock);\n}\n\nexport async function typecheckCodeBlocks(\n source: string,\n options: TypecheckCodeBlockOptions = {},\n): Promise<CodeBlockDiagnostic[]> {\n if (!source.includes(\"```\")) {\n return [];\n }\n\n const languages = new Set(\n (options.languages ?? [\"ts\", \"tsx\"]).map((language) => language.toLowerCase()),\n );\n const blocks = (await extractCodeBlocks(source)).filter((block) => {\n if (!languages.has(block.language.toLowerCase())) {\n return false;\n }\n return options.requireMeta === false || hasTypecheckMeta(block.meta);\n });\n if (blocks.length === 0) {\n return [];\n }\n\n const temp = await mkdtemp(join(tmpdir(), \"ox-content-code-blocks-\"));\n try {\n const files: string[] = [];\n await Promise.all(\n blocks.map(async (block, index) => {\n const extension = block.language.toLowerCase() === \"tsx\" ? \"tsx\" : \"ts\";\n const file = join(temp, `snippet-${index}.${extension}`);\n files.push(file);\n await writeFile(file, block.code);\n }),\n );\n\n try {\n await execFileAsync(\n options.tsgoCommand ?? \"tsgo\",\n [\"--noEmit\", \"--pretty\", \"false\", ...files],\n {\n cwd: process.cwd(),\n maxBuffer: 1024 * 1024 * 4,\n },\n );\n return [];\n } catch (error) {\n const output = commandOutput(error);\n return [\n {\n ruleId: \"code-block-typecheck\",\n severity: \"error\",\n message: output || \"TypeScript code block type-checking failed.\",\n line: blocks[0]?.startLine ?? 1,\n column: 1,\n endLine: blocks[0]?.startLine ?? 1,\n endColumn: 1,\n language: \"ts\",\n },\n ];\n }\n } finally {\n await rm(temp, { recursive: true, force: true });\n }\n}\n\nfunction hasTypecheckMeta(meta: string): boolean {\n return meta\n .split(/\\s+/)\n .some(\n (token) => token === \"typecheck\" || token === \"twoslash\" || token.startsWith(\"typecheck=\"),\n );\n}\n\nfunction commandOutput(error: unknown): string {\n if (!error || typeof error !== \"object\") {\n return \"\";\n }\n const value = error as { stdout?: unknown; stderr?: unknown; message?: unknown };\n return [value.stdout, value.stderr, value.message]\n .filter((part): part is string => typeof part === \"string\" && part.trim().length > 0)\n .join(\"\\n\")\n .trim();\n}\n\nfunction normalizeBlock(block: {\n language: string;\n meta: string;\n code: string;\n startLine: number;\n endLine: number;\n}): ExtractedCodeBlock {\n return block;\n}\n\nfunction normalizeDiagnostic(diagnostic: {\n ruleId: string;\n severity: string;\n message: string;\n line: number;\n column: number;\n endLine: number;\n endColumn: number;\n language?: string;\n}): CodeBlockDiagnostic {\n return {\n ...diagnostic,\n severity:\n diagnostic.severity === \"error\" || diagnostic.severity === \"info\"\n ? diagnostic.severity\n : \"warning\",\n };\n}\n","/**\n * Markdown Transformation Engine\n *\n * This module handles the complete transformation pipeline for Markdown files,\n * converting raw Markdown content into JavaScript modules that can be imported\n * by web applications. The transformation process includes:\n *\n * 1. **Parsing**: Uses Rust-based parser via NAPI bindings for high performance\n * 2. **Rendering**: Converts parsed AST to semantic HTML\n * 3. **Enhancement**: Applies syntax highlighting, Mermaid diagram rendering, etc.\n * 4. **Code Generation**: Generates JavaScript/TypeScript module code\n *\n * The generated modules export:\n * - `html`: Rendered HTML content\n * - `frontmatter`: Parsed YAML metadata\n * - `toc`: Hierarchical table of contents\n * - `render`: Client-side render function for dynamic updates\n *\n * @example\n * ```typescript\n * import { transformMarkdown } from './transform';\n *\n * const content = await transformMarkdown(\n * '# Hello\\n\\nWorld',\n * 'path/to/file.md',\n * resolvedOptions\n * );\n *\n * console.log(content.html); // '<h1>Hello</h1><p>World</p>'\n * console.log(content.toc); // [{ depth: 1, text: 'Hello', slug: 'hello', children: [] }]\n * ```\n */\n\nimport type { ResolvedOptions, TransformResult, TocEntry } from \"./types\";\nimport { highlightCode } from \"./highlight\";\nimport { importNapiModule } from \"./napi\";\nimport { transformMermaidStatic } from \"./plugins/mermaid\";\nimport { transformBuiltinEmbeds } from \"./plugins\";\nimport { protectMermaidSvgs, restoreMermaidSvgs } from \"./plugins/mermaid-protect\";\nimport { typecheckCodeBlocks } from \"./code-blocks\";\n\n/**\n * NAPI bindings for Rust-based Markdown processing.\n *\n * Provides access to compiled Rust functions for high-performance\n * Markdown parsing and rendering operations.\n */\ninterface NapiBindings {\n /**\n * Simple Markdown parser and renderer in one step.\n * Faster for simple use cases but lacks advanced features.\n *\n * @param source - Raw Markdown content\n * @param options - Parser configuration (GFM flag)\n * @returns Rendered HTML and parsing errors\n */\n parseAndRender: (\n source: string,\n options?: { gfm?: boolean },\n ) => { html: string; errors: string[] };\n\n /**\n * Full-featured Markdown transformation pipeline.\n * Handles frontmatter extraction, TOC generation, and advanced parsing.\n *\n * @param source - Raw Markdown content (may include frontmatter)\n * @param options - Comprehensive transformation options\n * @returns Transformed result with HTML, metadata, and TOC\n */\n transform: (\n source: string,\n options?: JsTransformOptions,\n ) => {\n html: string;\n frontmatter: string;\n toc: Array<{ depth: number; text: string; slug: string; children?: TocEntry[] }>;\n errors: string[];\n };\n\n /**\n * Generates an OG image as SVG.\n *\n * @param data - OG image data (title, description, etc.)\n * @param config - Optional OG image configuration\n * @returns SVG string\n */\n generateOgImageSvg: (data: OgImageData, config?: OgImageConfig) => string;\n\n /**\n * Restores code block metadata after JavaScript-side syntax highlighting.\n *\n * @param originalHtml - HTML before syntax highlighting\n * @param highlightedHtml - HTML after Shiki highlighting\n * @returns Highlighted HTML with original code block metadata reapplied\n */\n mergeHighlightedCodeBlocks: (originalHtml: string, highlightedHtml: string) => string;\n\n sanitizeHtml: (html: string, options?: JsSanitizeOptions) => string;\n\n lintCodeBlocks: (source: string, options?: JsCodeBlockLintOptions) => JsCodeBlockDiagnostic[];\n}\n\n/**\n * OG image data for generating social media preview images.\n */\nexport interface OgImageData {\n /** Page title */\n title: string;\n /** Page description */\n description?: string;\n /** Site name */\n siteName?: string;\n /** Author name */\n author?: string;\n}\n\n/**\n * OG image configuration.\n */\nexport interface OgImageConfig {\n /** Image width in pixels */\n width?: number;\n /** Image height in pixels */\n height?: number;\n /** Background color (hex) */\n backgroundColor?: string;\n /** Text color (hex) */\n textColor?: string;\n /** Title font size */\n titleFontSize?: number;\n /** Description font size */\n descriptionFontSize?: number;\n}\n\n/**\n * Options for Rust-based Markdown transformation.\n *\n * Controls which Markdown extensions and features are enabled\n * during parsing and rendering.\n */\ninterface JsTransformOptions {\n /**\n * Enable GitHub Flavored Markdown extensions.\n * Includes tables, task lists, strikethrough, and autolinks.\n * @default false\n */\n gfm?: boolean;\n\n /**\n * Enable footnotes syntax ([^1]: definition).\n * @default false\n */\n footnotes?: boolean;\n\n /**\n * Enable task list syntax (- [ ] unchecked, - [x] checked).\n * @default false\n */\n taskLists?: boolean;\n\n /**\n * Enable table rendering (GFM extension).\n * Requires GFM to be enabled for full functionality.\n * @default false\n */\n tables?: boolean;\n\n /**\n * Enable strikethrough syntax (~~text~~).\n * Requires GFM to be enabled.\n * @default false\n */\n strikethrough?: boolean;\n\n /**\n * Enable automatic link conversion (URLs become clickable).\n * @default false\n */\n autolinks?: boolean;\n\n /**\n * Parse YAML frontmatter before transforming.\n * @default true\n */\n frontmatter?: boolean;\n\n /**\n * Maximum heading depth for table of contents.\n * Headings deeper than this level are excluded from TOC.\n * @default 3\n * @min 1\n * @max 6\n */\n tocMaxDepth?: number;\n\n /**\n * Convert `.md` links to `.html` links for SSG output.\n * @default false\n */\n convertMdLinks?: boolean;\n\n /**\n * Base URL for absolute link conversion (e.g., \"/\" or \"/docs/\").\n * @default \"/\"\n */\n baseUrl?: string;\n\n /**\n * Source file path for relative link resolution.\n * Used to determine if the current file is an index file.\n */\n sourcePath?: string;\n\n /**\n * Enable line annotations for code blocks using fence meta.\n * @default false\n */\n codeAnnotations?: boolean;\n\n /**\n * Fence meta key used to read code annotations.\n * @default \"annotate\"\n */\n codeAnnotationMetaKey?: string;\n\n /**\n * Code annotation syntax mode.\n * @default \"attribute\"\n */\n codeAnnotationSyntax?: \"attribute\" | \"vitepress\" | \"both\";\n\n /**\n * Enable line numbers for all code blocks by default.\n * @default false\n */\n codeAnnotationDefaultLineNumbers?: boolean;\n\n wikiLinks?: {\n enabled?: boolean;\n baseUrl?: string;\n };\n\n emojiShortcodes?: {\n enabled?: boolean;\n custom?: Record<string, string>;\n };\n\n attributes?: {\n enabled?: boolean;\n };\n\n cjkEmphasis?: boolean;\n\n codeImports?: {\n enabled?: boolean;\n rootDir?: string;\n };\n\n sanitize?: JsSanitizeOptions;\n\n editThisPage?: {\n enabled?: boolean;\n repoUrl?: string;\n branch?: string;\n rootDir?: string;\n label?: string;\n };\n}\n\ninterface JsSanitizeOptions {\n enabled?: boolean;\n allowedTags?: string[];\n allowedAttributes?: string[];\n allowedUrlSchemes?: string[];\n}\n\ninterface JsCodeBlockLintOptions {\n enabled?: boolean;\n languages?: string[];\n requireLanguage?: boolean;\n trailingSpaces?: boolean;\n}\n\ninterface JsCodeBlockDiagnostic {\n ruleId: string;\n severity: string;\n message: string;\n line: number;\n column: number;\n endLine: number;\n endColumn: number;\n language?: string;\n}\n\n/**\n * Cached NAPI bindings instance.\n * Loaded on first use and reused for subsequent transformations.\n * @internal\n */\nlet napiBindings: NapiBindings | null | undefined;\n\n/**\n * Flag to prevent repeated NAPI loading attempts.\n * Set to true after first load attempt (success or failure).\n * @internal\n */\nlet napiLoadAttempted = false;\n\n/**\n * Lazily loads and caches NAPI bindings.\n *\n * This function uses lazy loading to defer the import of NAPI bindings\n * until they're actually needed. The bindings are loaded only once and\n * cached for subsequent uses. If loading fails (e.g., bindings not built),\n * the failure is cached to avoid repeated load attempts.\n *\n * ## Performance Considerations\n *\n * The first call to this function may have a slight performance penalty\n * due to module loading. Subsequent calls use the cached result and are\n * essentially zero-cost.\n *\n * ## Error Handling\n *\n * If NAPI bindings are not available (not built, wrong architecture, etc.),\n * this function returns `null`. The caller should handle this gracefully\n * or provide fallback behavior.\n *\n * @returns Promise resolving to NAPI bindings or null if unavailable\n *\n * @example\n * ```typescript\n * // Simple check with fallback\n * const napi = await loadNapiBindings();\n * if (!napi) {\n * console.warn('NAPI bindings not available, using fallback');\n * return fallbackRender(content);\n * }\n *\n * // Use Rust implementation\n * const result = napi.transform(content, { gfm: true });\n * ```\n *\n * @internal\n */\nasync function loadNapiBindings(): Promise<NapiBindings | null> {\n // Return cached result (success or failure)\n if (napiLoadAttempted) {\n return napiBindings ?? null;\n }\n\n // Mark attempt as made to prevent retry loops\n napiLoadAttempted = true;\n\n try {\n // Dynamic import to handle cases where NAPI isn't built\n const mod = await importNapiModule();\n napiBindings = mod;\n return mod;\n } catch (error) {\n // NAPI not available (not built, missing dependencies, etc.)\n // Log for debugging but don't throw - allow graceful degradation\n if (process.env.DEBUG) {\n console.debug(\"[ox-content] NAPI bindings load failed:\", error);\n }\n napiBindings = null;\n return null;\n }\n}\n\n/**\n * Transforms Markdown content into a JavaScript module.\n *\n * This is the primary entry point for transforming Markdown files. It handles\n * the complete transformation pipeline including parsing, rendering, syntax\n * highlighting, and code generation.\n *\n * ## Pipeline Steps\n *\n * 1. **Parse & Render**: Uses Rust-based parser via NAPI for high performance\n * 2. **Extract Metadata**: Parses YAML frontmatter and generates table of contents\n * 3. **Enhance HTML**: Applies syntax highlighting and Mermaid diagram rendering\n * 4. **Generate Code**: Creates importable JavaScript module\n *\n * ## Generated Module Exports\n *\n * - `html` (string): Rendered HTML content with all enhancements applied\n * - `frontmatter` (object): Parsed YAML frontmatter as JavaScript object\n * - `toc` (array): Hierarchical table of contents entries\n * - `render` (function): Client-side render function for dynamic updates\n *\n * ## Markdown Features Supported\n *\n * The supported features depend on parser options:\n * - **Commonmark**: Headings, paragraphs, lists, code blocks, links, images\n * - **GFM Extensions**: Tables, task lists, strikethrough, autolinks\n * - **Enhancements**: Syntax highlighting, Mermaid diagrams, TOC generation\n * - **Metadata**: YAML frontmatter parsing\n *\n * ## Performance\n *\n * Uses Rust-based parsing via NAPI bindings for optimal performance. Falls back\n * gracefully if Rust bindings are unavailable.\n *\n * @param source - Raw Markdown source code (may include YAML frontmatter)\n * @param filePath - File path for source attribution and relative link resolution\n * @param options - Resolved plugin options controlling transformation behavior\n *\n * @returns Promise resolving to transformation result with HTML and metadata\n *\n * @throws Error if NAPI bindings are unavailable (can be handled gracefully)\n *\n * @example\n * ```typescript\n * import { transformMarkdown } from './transform';\n * import { resolveOptions } from './index';\n *\n * // Transform a Markdown file with YAML frontmatter\n * const markdown = `---\n * title: Getting Started\n * author: john\n * ---\n *\n * # Getting Started\n *\n * Welcome! This guide explains [transformMarkdown] function.\n *\n * ## Installation\n *\n * \\`\\`\\`bash\n * npm install @ox-content/vite-plugin\n * \\`\\`\\`\n * `;\n *\n * const options = resolveOptions({\n * highlight: true,\n * highlightTheme: 'github-dark',\n * toc: true,\n * gfm: true,\n * mermaid: true,\n * });\n *\n * const result = await transformMarkdown(markdown, 'docs/getting-started.md', options);\n *\n * // Generated module exports\n * console.log(result.html); // Rendered HTML with syntax highlighting\n * console.log(result.frontmatter); // { title: 'Getting Started', author: 'john' }\n * console.log(result.toc); // [{ depth: 1, text: 'Getting Started', ... }]\n * console.log(result.code); // ES module export statement\n * ```\n */\n/**\n * SSG-specific transform options.\n */\nexport interface SsgTransformOptions {\n /** Convert `.md` links to `.html` links */\n convertMdLinks?: boolean;\n /** Base URL for absolute link conversion */\n baseUrl?: string;\n /** Source file path for relative link resolution */\n sourcePath?: string;\n}\n\nexport async function transformMarkdown(\n source: string,\n filePath: string,\n options: ResolvedOptions,\n ssgOptions?: SsgTransformOptions,\n): Promise<TransformResult> {\n const napi = await loadNapiBindings();\n\n if (!napi) {\n throw new Error(\n \"[ox-content] NAPI bindings not available. Please ensure @ox-content/napi is built.\",\n );\n }\n\n // Use Rust-based transformation, including frontmatter preparation.\n runCodeBlockLint(source, napi, options);\n await runCodeBlockTypecheck(source, options);\n\n const result = napi.transform(source, {\n gfm: options.gfm,\n footnotes: options.footnotes,\n taskLists: options.taskLists,\n tables: options.tables,\n strikethrough: options.strikethrough,\n frontmatter: options.frontmatter,\n tocMaxDepth: options.tocMaxDepth,\n convertMdLinks: ssgOptions?.convertMdLinks,\n baseUrl: ssgOptions?.baseUrl,\n sourcePath: ssgOptions?.sourcePath ?? filePath,\n codeAnnotations: options.codeAnnotations?.enabled ?? false,\n codeAnnotationMetaKey: options.codeAnnotations?.metaKey ?? \"annotate\",\n codeAnnotationSyntax: options.codeAnnotations?.notation ?? \"attribute\",\n codeAnnotationDefaultLineNumbers: options.codeAnnotations?.defaultLineNumbers ?? false,\n wikiLinks: options.wikiLinks?.enabled\n ? {\n enabled: true,\n baseUrl: options.wikiLinks.baseUrl,\n }\n : undefined,\n emojiShortcodes: options.emojiShortcodes?.enabled\n ? {\n enabled: true,\n custom: options.emojiShortcodes.custom,\n }\n : undefined,\n attributes: options.attrs?.enabled ? { enabled: true } : undefined,\n cjkEmphasis: options.cjkEmphasis ?? false,\n codeImports: options.codeImports?.enabled\n ? {\n enabled: true,\n rootDir: options.codeImports.rootDir,\n }\n : undefined,\n // Sanitize once at the end of the JS pipeline so opt-in embeds can be\n // expanded before the allow-list is applied.\n sanitize: undefined,\n editThisPage: options.editThisPage?.enabled\n ? {\n enabled: true,\n repoUrl: options.editThisPage.repoUrl,\n branch: options.editThisPage.branch,\n rootDir: options.editThisPage.rootDir,\n label: options.editThisPage.label,\n }\n : undefined,\n });\n\n if (result.errors.length > 0) {\n console.warn(\"[ox-content] Transform warnings:\", result.errors);\n }\n\n let html = result.html;\n const frontmatter = parseFrontmatterJson(result.frontmatter);\n\n const toc = options.toc ? result.toc.map(normalizeTocEntry) : [];\n\n // Transform mermaid diagrams before highlighting to avoid entity re-encoding\n if (options.mermaid) {\n html = await transformMermaidStatic(html);\n }\n\n // Protect mermaid SVGs from rehype processing (which corrupts <br /> in foreignObjects)\n const { html: protectedHtml, svgs } = protectMermaidSvgs(html);\n html = protectedHtml;\n\n // Apply syntax highlighting if enabled\n if (options.highlight) {\n const originalHtml = html;\n const highlightedHtml = await highlightCode(\n html,\n options.highlightTheme,\n options.highlightLangs,\n );\n html = napi.mergeHighlightedCodeBlocks(originalHtml, highlightedHtml);\n }\n\n // Render static built-in embeds while Mermaid SVG placeholders are protected.\n html = await transformBuiltinEmbeds(\n html,\n options.embeds ?? {\n github: {},\n openGraph: {},\n },\n );\n\n // Restore protected SVGs\n html = restoreMermaidSvgs(html, svgs);\n\n if (options.sanitize?.enabled) {\n html = napi.sanitizeHtml(html, toJsSanitizeOptions(options.sanitize));\n }\n\n // Generate JavaScript module code\n const code = generateModuleCode(html, frontmatter, toc, filePath, options);\n\n return {\n code,\n html,\n frontmatter,\n toc,\n };\n}\n\nasync function runCodeBlockTypecheck(source: string, options: ResolvedOptions): Promise<void> {\n const typecheck = options.codeBlockTypecheck;\n if (!typecheck?.enabled || !source.includes(\"```\")) {\n return;\n }\n\n const diagnostics = await typecheckCodeBlocks(source, {\n languages: typecheck.languages,\n requireMeta: typecheck.requireMeta,\n tsgoCommand: typecheck.tsgoCommand,\n });\n if (diagnostics.length === 0) {\n return;\n }\n\n const message = diagnostics\n .slice(0, 3)\n .map((diagnostic) => `${diagnostic.ruleId} at ${diagnostic.line}: ${diagnostic.message}`)\n .join(\"\\n\");\n if (typecheck.mode === \"error\") {\n throw new Error(`[ox-content] Code block type-checking failed:\\n${message}`);\n }\n console.warn(`[ox-content] Code block type-checking warnings:\\n${message}`);\n}\n\nfunction runCodeBlockLint(source: string, napi: NapiBindings, options: ResolvedOptions): void {\n const lint = options.codeBlockLint;\n if (!lint?.enabled || !source.includes(\"```\")) {\n return;\n }\n\n const diagnostics = napi.lintCodeBlocks(source, {\n enabled: true,\n languages: lint.languages,\n requireLanguage: lint.requireLanguage,\n trailingSpaces: lint.trailingSpaces,\n });\n if (diagnostics.length === 0) {\n return;\n }\n\n const message = diagnostics\n .slice(0, 5)\n .map((diagnostic) => {\n return `${diagnostic.ruleId} at ${diagnostic.line}:${diagnostic.column} ${diagnostic.message}`;\n })\n .join(\"\\n\");\n if (lint.mode === \"error\") {\n throw new Error(`[ox-content] Code block lint failed:\\n${message}`);\n }\n console.warn(`[ox-content] Code block lint warnings:\\n${message}`);\n}\n\nfunction toJsSanitizeOptions(options: ResolvedOptions[\"sanitize\"]): JsSanitizeOptions {\n return {\n enabled: true,\n allowedTags: options.allowedTags,\n allowedAttributes: options.allowedAttributes,\n allowedUrlSchemes: options.allowedUrlSchemes,\n };\n}\n\nfunction parseFrontmatterJson(json: string): Record<string, unknown> {\n if (!json) {\n return {};\n }\n\n try {\n const value = JSON.parse(json);\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n\nfunction normalizeTocEntry(entry: {\n depth: number;\n text: string;\n slug: string;\n children?: TocEntry[];\n}): TocEntry {\n return {\n depth: entry.depth,\n text: entry.text,\n slug: entry.slug,\n children: (entry.children ?? []).map(normalizeTocEntry),\n };\n}\n\n/**\n * Generates the JavaScript module code.\n */\nfunction generateModuleCode(\n html: string,\n frontmatter: Record<string, unknown>,\n toc: TocEntry[],\n filePath: string,\n _options: ResolvedOptions,\n): string {\n const htmlJson = JSON.stringify(html);\n const frontmatterJson = JSON.stringify(frontmatter);\n const tocJson = JSON.stringify(toc);\n\n return `\n// Generated by @ox-content/vite-plugin\n// Source: ${filePath}\n\n/**\n * Rendered HTML content.\n */\nexport const html = ${htmlJson};\n\n/**\n * Parsed frontmatter.\n */\nexport const frontmatter = ${frontmatterJson};\n\n/**\n * Table of contents.\n */\nexport const toc = ${tocJson};\n\n/**\n * Default export with all data.\n */\nexport default {\n html,\n frontmatter,\n toc,\n};\n\n// HMR support\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (newModule) {\n // Trigger re-render with new content\n import.meta.hot.invalidate();\n }\n });\n}\n`;\n}\n\n/**\n * Extracts imports from Markdown content.\n *\n * Supports importing components for interactive islands.\n */\nexport function extractImports(content: string): string[] {\n const importRegex = /^import\\s+.+\\s+from\\s+['\"](.+)['\"]/gm;\n const imports: string[] = [];\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n return imports;\n}\n\n/**\n * Generates an OG image SVG using the Rust-based generator.\n *\n * This function uses the Rust NAPI bindings to generate SVG-based\n * OG images for social media previews. The SVG can be served directly\n * or converted to PNG/JPEG for broader compatibility.\n *\n * In the future, custom JS templates can be provided to override\n * the default Rust-based template.\n *\n * @param data - OG image data (title, description, etc.)\n * @param config - Optional OG image configuration\n * @returns SVG string or null if NAPI bindings are unavailable\n */\nexport async function generateOgImageSvg(\n data: OgImageData,\n config?: OgImageConfig,\n): Promise<string | null> {\n const napi = await loadNapiBindings();\n if (!napi) {\n return null;\n }\n\n // Convert config to NAPI format (camelCase to snake_case)\n const napiConfig = config\n ? {\n width: config.width,\n height: config.height,\n backgroundColor: config.backgroundColor,\n textColor: config.textColor,\n titleFontSize: config.titleFontSize,\n descriptionFontSize: config.descriptionFontSize,\n }\n : undefined;\n\n return napi.generateOgImageSvg(data, napiConfig);\n}\n","/**\n * Source Documentation Extraction and Generation\n *\n * This module provides comprehensive tools for extracting JSDoc/TSDoc comments\n * from TypeScript/JavaScript source files and automatically generating Markdown\n * documentation.\n *\n * ## Features\n *\n * - **Automatic Extraction**: Parses JSDoc comments from functions, classes, interfaces, and types\n * - **Flexible Filtering**: Include/exclude patterns for selective documentation\n * - **Markdown Generation**: Converts extracted docs to organized Markdown files\n * - **Navigation Generation**: Auto-generates sidebar navigation metadata\n * - **GitHub Links**: Includes clickable links to source code on GitHub\n *\n * ## Supported JSDoc Tags\n *\n * - `@param {type} name - description` - Function parameter documentation\n * - `@returns {type} description` - Return value documentation\n * - `@example` - Code examples (multi-line blocks)\n * - `@private` - Mark item as private (excluded from docs if private=false)\n * - `@default value` - Default parameter value\n * - Custom tags are preserved in the `tags` field\n *\n * ## Usage Flow\n *\n * 1. Call `extractDocs()` to parse source files\n * 2. Call `generateMarkdown()` to create Markdown content\n * 3. Call `writeDocs()` to write files to output directory\n * 4. Generated nav.ts can be imported for sidebar navigation\n *\n * @example\n * ```typescript\n * import { extractDocs, generateMarkdown, writeDocs } from './docs';\n *\n * const docsOptions = {\n * enabled: true,\n * src: ['./src'],\n * out: './docs/api',\n * include: ['**\\/*.ts'],\n * exclude: ['**\\/*.test.ts'],\n * groupBy: 'file',\n * githubUrl: 'https://github.com/user/project',\n * };\n *\n * const extracted = await extractDocs(['./src'], docsOptions);\n * const markdown = generateMarkdown(extracted, docsOptions);\n * await writeDocs(markdown, './docs/api', extracted, docsOptions);\n * ```\n */\n\nimport type {\n ResolvedDocsOptions,\n ExtractedDocs,\n DocEntry,\n ResolvedDocsEntryPoint,\n DocsOptions,\n} from \"./types\";\nimport { importNapiModule, importNapiModuleSync } from \"./napi\";\n\nconst DEFAULT_DOCS_INCLUDE = [\n \"**/*.ts\",\n \"**/*.tsx\",\n \"**/*.js\",\n \"**/*.jsx\",\n \"**/*.mts\",\n \"**/*.mjs\",\n \"**/*.cts\",\n \"**/*.cjs\",\n];\n\n/**\n * Extracts JSDoc documentation from source files in specified directories.\n *\n * This function recursively searches directories for source files matching\n * the include/exclude patterns, then extracts all documented items (functions,\n * classes, interfaces, types) from those files.\n *\n * ## Process\n *\n * 1. **File Discovery**: Recursively walks directories, applying filters\n * 2. **File Reading**: Loads each matching file's content\n * 3. **JSDoc Extraction**: Parses JSDoc comments using the native parser\n * 4. **Declaration Matching**: Pairs JSDoc comments with source declarations\n * 5. **Result Collection**: Aggregates extracted documentation by file\n *\n * ## Include/Exclude Patterns\n *\n * Patterns support:\n * - `**` - Match any directory structure\n * - `*` - Match any filename\n * - Standard glob patterns (e.g., `**\\/*.test.ts`)\n *\n * ## Performance Considerations\n *\n * - Uses filesystem I/O which can be slow for large codebases\n * - Consider using more specific include patterns to reduce file scanning\n * - Results are not cached; call once per build/dev session\n *\n * @param srcDirs - Array of source directory paths to scan\n * @param options - Documentation extraction options (filters, grouping, etc.)\n *\n * @returns Promise resolving to array of extracted documentation by file.\n * Each ExtractedDocs object contains file path and array of DocEntry items.\n *\n * @example\n * ```typescript\n * const docs = await extractDocs(\n * ['./packages/vite-plugin/src'],\n * {\n * enabled: true,\n * src: [],\n * out: 'docs',\n * include: ['**\\/*.ts'],\n * exclude: ['**\\/*.test.ts', '**\\/*.spec.ts'],\n * format: 'markdown',\n * private: false,\n * toc: true,\n * groupBy: 'file',\n * generateNav: true,\n * }\n * );\n *\n * // Returns:\n * // [\n * // {\n * // file: '/path/to/transform.ts',\n * // entries: [\n * // { name: 'transformMarkdown', kind: 'function', ... },\n * // { name: 'loadNapiBindings', kind: 'function', ... },\n * // ]\n * // },\n * // ...\n * // ]\n * ```\n */\nexport async function extractDocs(\n srcDirs: string[],\n options: ResolvedDocsOptions,\n): Promise<ExtractedDocs[]> {\n const napi = await importNapiModule();\n\n if (options.entryPoints?.length) {\n const extractDocsFromEntryPoints = (\n napi as {\n extractDocsFromEntryPoints?: (\n entryPoints: ResolvedDocsEntryPoint[],\n options?: {\n root?: string;\n private?: boolean;\n internal?: boolean;\n typeParameters?: boolean;\n },\n ) => Array<{ file: string; entries: DocEntry[] }>;\n }\n ).extractDocsFromEntryPoints;\n\n if (!extractDocsFromEntryPoints) {\n throw new Error(\n \"[ox-content] extractDocsFromEntryPoints is not available from @ox-content/napi.\",\n );\n }\n\n return extractDocsFromEntryPoints(options.entryPoints, {\n root: process.cwd(),\n private: options.private,\n internal: options.internal,\n typeParameters: options.typeParameters,\n }).map((doc) => ({ file: doc.file, entries: doc.entries }));\n }\n\n const extractDocsFromDirectories = (\n napi as {\n extractDocsFromDirectories?: (\n srcDirs: string[],\n include: string[],\n exclude: string[],\n includePrivate?: boolean,\n includeInternal?: boolean,\n typeParameters?: boolean,\n ) => Array<{ file: string; entries: DocEntry[] }>;\n }\n ).extractDocsFromDirectories;\n\n if (!extractDocsFromDirectories) {\n throw new Error(\n \"[ox-content] extractDocsFromDirectories is not available from @ox-content/napi.\",\n );\n }\n\n return extractDocsFromDirectories(\n srcDirs,\n options.include,\n options.exclude,\n options.private,\n options.internal,\n options.typeParameters,\n ).map((doc) => ({ file: doc.file, entries: doc.entries }));\n}\n\n/**\n * Generates Markdown documentation from extracted docs.\n */\nexport function generateMarkdown(\n docs: ExtractedDocs[],\n options: ResolvedDocsOptions,\n): Record<string, string> {\n const napi = importNapiModuleSync();\n\n if (typeof napi.generateDocsMarkdown !== \"function\") {\n throw new Error(\n \"[ox-content] generateDocsMarkdown is not available from @ox-content/napi. Please rebuild the NAPI package.\",\n );\n }\n\n return napi.generateDocsMarkdown(toRustDocsModules(docs), {\n groupBy: options.groupBy,\n githubUrl: options.githubUrl,\n linkStyle: options.linkStyle,\n basePath: options.basePath,\n pathStrategy: options.pathStrategy,\n renderStyle: options.renderStyle,\n });\n}\n\n/**\n * Writes generated documentation to the output directory.\n */\nexport async function writeDocs(\n docs: Record<string, string>,\n outDir: string,\n extractedDocs?: ExtractedDocs[],\n options?: ResolvedDocsOptions,\n): Promise<void> {\n const napi = importNapiModuleSync();\n\n if (typeof napi.writeGeneratedDocs !== \"function\") {\n throw new Error(\n \"[ox-content] writeGeneratedDocs is not available from @ox-content/napi. Please rebuild the NAPI package.\",\n );\n }\n\n napi.writeGeneratedDocs(\n docs,\n outDir,\n extractedDocs ? toRustDocsModules(extractedDocs) : undefined,\n {\n generateNav: options?.generateNav ?? false,\n groupBy: options?.groupBy ?? \"file\",\n generatedAt: new Date().toISOString(),\n basePath: options?.basePath,\n pathStrategy: options?.pathStrategy,\n },\n );\n}\n\nexport function toRustDocsModules(docs: ExtractedDocs[]) {\n return docs.map((doc) => ({\n file: doc.file,\n entries: doc.entries.map((entry) => ({\n name: entry.name,\n kind: entry.kind,\n description: entry.description,\n params: entry.params,\n returns: entry.returns,\n examples: entry.examples,\n tags: entry.tags\n ? Object.entries(entry.tags).map(([tag, value]) => ({ tag, value }))\n : undefined,\n private: entry.private ?? false,\n file: entry.file,\n line: entry.line,\n endLine: entry.endLine,\n signature: entry.signature,\n members: entry.members,\n })),\n }));\n}\n\n/**\n * Resolves docs options with defaults.\n */\nexport function resolveDocsOptions(options: false): false;\nexport function resolveDocsOptions(options?: DocsOptions): ResolvedDocsOptions;\nexport function resolveDocsOptions(\n options: DocsOptions | false | undefined,\n): ResolvedDocsOptions | false;\nexport function resolveDocsOptions(\n options: DocsOptions | false | undefined,\n): ResolvedDocsOptions | false {\n if (options === false) {\n return false;\n }\n\n const opts = options || {};\n\n return {\n enabled: opts.enabled ?? true,\n src: opts.src ?? [\"./src\"],\n out: opts.out ?? \"docs/api\",\n include: opts.include ?? DEFAULT_DOCS_INCLUDE,\n exclude: opts.exclude ?? [\"**/*.test.*\", \"**/*.spec.*\", \"node_modules\"],\n entryPoints: opts.entryPoints?.map((entryPoint) =>\n typeof entryPoint === \"string\" ? { path: entryPoint } : entryPoint,\n ),\n format: opts.format ?? \"markdown\",\n private: opts.private ?? false,\n internal: opts.internal ?? false,\n toc: false,\n groupBy: opts.groupBy ?? \"file\",\n githubUrl: opts.githubUrl,\n linkStyle: opts.linkStyle ?? \"markdown\",\n basePath: opts.basePath,\n pathStrategy: opts.pathStrategy ?? \"flat\",\n renderStyle: opts.renderStyle ?? \"html\",\n typeParameters: opts.typeParameters ?? false,\n generateNav: opts.generateNav ?? true,\n };\n}\n","/**\n * HTML → PNG renderer using Chromium screenshots via Playwright.\n */\n\nimport * as path from \"path\";\nimport type { Page } from \"playwright\";\n\n/**\n * Wraps template HTML in a minimal document with viewport locked to given dimensions.\n */\nfunction wrapHtml(bodyHtml: string, width: number, height: number, useBaseUrl: boolean): string {\n const baseTag = useBaseUrl ? `\\n<base href=\"http://localhost/\">` : \"\";\n return `<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"UTF-8\">${baseTag}\n<style>\n* { margin: 0; padding: 0; box-sizing: border-box; }\nhtml, body { width: ${width}px; height: ${height}px; overflow: hidden; }\n</style>\n</head>\n<body>${bodyHtml}</body>\n</html>`;\n}\n\n/**\n * Renders an HTML string to a PNG buffer using Chromium.\n *\n * @param page - Playwright page instance\n * @param html - HTML string from template function\n * @param width - Image width\n * @param height - Image height\n * @param publicDir - Optional public directory for serving local assets (images, fonts, etc.)\n * @returns PNG buffer\n */\nexport async function renderHtmlToPng(\n page: Page,\n html: string,\n width: number,\n height: number,\n publicDir?: string,\n): Promise<Buffer> {\n await page.setViewportSize({ width, height });\n\n // Serve local assets from the public directory\n if (publicDir) {\n const fs = await import(\"fs/promises\");\n await page.route(\"**/*\", async (route) => {\n const url = new URL(route.request().url());\n // Only intercept paths that look like local assets (not data: or blob:)\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n await route.continue();\n return;\n }\n const filePath = path.join(publicDir, url.pathname);\n try {\n const body = await fs.readFile(filePath);\n const ext = path.extname(filePath).toLowerCase();\n const mimeTypes: Record<string, string> = {\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n };\n await route.fulfill({\n body,\n contentType: mimeTypes[ext] || \"application/octet-stream\",\n });\n } catch {\n await route.continue();\n }\n });\n }\n\n const fullHtml = wrapHtml(html, width, height, !!publicDir);\n await page.setContent(fullHtml, { waitUntil: \"networkidle\" });\n\n const screenshot = await page.screenshot({\n type: \"png\",\n clip: { x: 0, y: 0, width, height },\n });\n\n return Buffer.from(screenshot);\n}\n","/**\n * Chromium browser session with automatic cleanup via Explicit Resource Management.\n *\n * Usage:\n * await using session = await openBrowser();\n * const png = await session.renderPage(html, 1200, 630);\n * // browser.close() is called automatically when session goes out of scope\n */\n\nimport type { Page } from \"playwright\";\nimport { renderHtmlToPng } from \"./renderer\";\n\nconst PLAYWRIGHT_BROWSER_INSTALL_HINT =\n \"Install Playwright browsers with `npx playwright install chromium` to enable OG image generation.\";\n\nlet chromiumUnavailableWarned = false;\n\n/**\n * A browser session that can render HTML pages to PNG.\n * Implements AsyncDisposable for automatic cleanup via `await using`.\n */\nexport interface OgBrowserSession extends AsyncDisposable {\n renderPage(html: string, width: number, height: number, publicDir?: string): Promise<Buffer>;\n}\n\n/**\n * Opens a Chromium browser and returns a session for rendering OG images.\n * Returns null if Playwright/Chromium is not available.\n *\n * The session implements AsyncDisposable — use `await using` for automatic cleanup:\n * ```ts\n * await using session = await openBrowser();\n * if (!session) return;\n * const png = await session.renderPage(html, 1200, 630);\n * ```\n */\nexport async function openBrowser(): Promise<OgBrowserSession | null> {\n try {\n const { chromium } = await import(\"playwright\");\n const browser = await chromium.launch({\n headless: true,\n args: [\n \"--no-sandbox\",\n \"--disable-setuid-sandbox\",\n \"--disable-dev-shm-usage\",\n \"--disable-gpu\",\n ],\n });\n\n return {\n async renderPage(\n html: string,\n width: number,\n height: number,\n publicDir?: string,\n ): Promise<Buffer> {\n const page: Page = await browser.newPage();\n try {\n return await renderHtmlToPng(page, html, width, height, publicDir);\n } finally {\n await page.close();\n }\n },\n\n async [Symbol.asyncDispose]() {\n try {\n await browser.close();\n } catch {\n // Ignore close errors\n }\n },\n };\n } catch (err) {\n warnChromiumUnavailableOnce(err);\n return null;\n }\n}\n\nfunction warnChromiumUnavailableOnce(err: unknown): void {\n if (chromiumUnavailableWarned) {\n return;\n }\n\n chromiumUnavailableWarned = true;\n console.warn(\n `[ox-content:og-image] Chromium not available, skipping OG image generation. ${formatChromiumUnavailableDetail(\n err,\n )}`,\n );\n}\n\nfunction formatChromiumUnavailableDetail(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err);\n\n if (\n message.includes(\"Executable doesn't exist\") ||\n message.includes(\"Please run the following command to download new browsers\")\n ) {\n return PLAYWRIGHT_BROWSER_INSTALL_HINT;\n }\n\n return (\n message\n .split(/\\r?\\n/)\n .find((line) => line.trim())\n ?.trim() ?? \"Unknown launch error.\"\n );\n}\n","/**\n * Default OG image template.\n *\n * Uses inline HTML/CSS for a flat, low-color brand card with title,\n * description, siteName, and tags. No external dependencies required.\n */\n\nimport type { OgImageTemplateFn, OgImageTemplateProps } from \"./types\";\n\n/**\n * Escapes HTML special characters.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction normalizeBrandValue(str: string): string {\n return str.replace(/\\s+/g, \"\").toLowerCase();\n}\n\nfunction renderWordmarkSvg(): string {\n return `<svg width=\"430\" height=\"102\" viewBox=\"0 0 270 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"ogWordmarkGradient\" x1=\"286\" y1=\"10\" x2=\"320\" y2=\"54\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"#355cff\"/>\n <stop offset=\"100%\" stop-color=\"#74c7ff\"/>\n </linearGradient>\n </defs>\n <text\n x=\"2\"\n y=\"43\"\n fill=\"#eff6ff\"\n font-family=\"IBM Plex Sans, IBM Plex Mono, Avenir Next, Segoe UI, sans-serif\"\n font-size=\"34\"\n font-weight=\"700\"\n letter-spacing=\"-1.4\"\n >\n OXCONTENT\n </text>\n <text\n x=\"213\"\n y=\"43.5\"\n fill=\"#eff6ff\"\n font-family=\"IBM Plex Sans, IBM Plex Mono, Avenir Next, Segoe UI, sans-serif\"\n font-size=\"40\"\n font-weight=\"400\"\n >\n (\n </text>\n <g transform=\"translate(216 9) scale(0.089) rotate(-7 256 256)\">\n <path\n d=\"M161 96H286C298 96 309 101 318 110L352 144C361 153 366 164 366 176V386C366 399 355 410 342 410H161C148 410 138 399 138 386V120C138 107 148 96 161 96Z\"\n fill=\"url(#ogWordmarkGradient)\"\n />\n </g>\n <text\n x=\"252\"\n y=\"43.5\"\n fill=\"#eff6ff\"\n font-family=\"IBM Plex Sans, IBM Plex Mono, Avenir Next, Segoe UI, sans-serif\"\n font-size=\"40\"\n font-weight=\"400\"\n >\n )\n </text>\n</svg>`;\n}\n\n/**\n * Returns the built-in default template function.\n */\nexport function getDefaultTemplate(): OgImageTemplateFn {\n return function defaultTemplate(props: OgImageTemplateProps): string {\n const { title, description, siteName } = props;\n const rawBrand = siteName?.trim() ? siteName : \"Ox Content\";\n const isBrandCard = normalizeBrandValue(title) === normalizeBrandValue(rawBrand);\n\n const heroTitle = isBrandCard ? \"cargo doc for JavaScript\" : title;\n const heroDescription = isBrandCard\n ? \"Rust-powered docs and high-performance Markdown tooling.\"\n : description && description.trim().length > 0\n ? description\n : \"Rust-powered docs and Markdown tooling.\";\n const descriptionHtml =\n heroDescription.trim().length > 0\n ? `<p style=\"max-width:760px;font-size:28px;color:#93a4c3;line-height:1.45;margin:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;\">${escapeHtml(heroDescription)}</p>`\n : \"\";\n\n return `<div style=\"width:100%;height:100%;position:relative;overflow:hidden;box-sizing:border-box;padding:56px 64px 52px;background:#0b1220;font-family:'IBM Plex Sans','Avenir Next','Segoe UI',system-ui,sans-serif;color:#eff6ff;border:1px solid #223252;border-top:4px solid #4f6fae;\">\n <div style=\"position:relative;z-index:1;display:flex;flex-direction:column;height:100%;\">\n <div style=\"display:flex;align-items:flex-start;\">${renderWordmarkSvg()}</div>\n <div style=\"display:flex;flex-direction:column;justify-content:center;gap:24px;max-width:860px;flex:1;padding:22px 0 0;\">\n <h1 style=\"font-size:78px;font-weight:700;color:#eff6ff;line-height:1.02;letter-spacing:-0.055em;margin:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;\">${escapeHtml(heroTitle)}</h1>\n ${descriptionHtml}\n </div>\n </div>\n</div>`;\n };\n}\n","/**\n * Content-hash based caching for OG images.\n *\n * Uses SHA256 of (template source + props + options) to determine\n * if a re-render is needed. Cache dir: .cache/og-images\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\n\n/**\n * Computes a cache key from template + props + options.\n */\nexport function computeCacheKey(\n templateSource: string,\n props: Record<string, unknown>,\n width: number,\n height: number,\n): string {\n const data = JSON.stringify({ templateSource, props, width, height });\n return crypto.createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\n/**\n * Checks if a cached PNG exists for the given key.\n * Returns the cached file path if found, null otherwise.\n */\nexport async function getCached(cacheDir: string, key: string): Promise<Buffer | null> {\n const filePath = path.join(cacheDir, `${key}.png`);\n try {\n return await fs.readFile(filePath);\n } catch {\n return null;\n }\n}\n\n/**\n * Writes a PNG buffer to the cache.\n */\nexport async function writeCache(cacheDir: string, key: string, png: Buffer): Promise<void> {\n await fs.mkdir(cacheDir, { recursive: true });\n const filePath = path.join(cacheDir, `${key}.png`);\n await fs.writeFile(filePath, png);\n}\n","/**\n * Public API for Chromium-based OG image generation.\n *\n * Orchestrates browser lifecycle, template resolution, caching,\n * and batch rendering with concurrency control.\n */\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\nimport { openBrowser } from \"./browser\";\nimport type { OgBrowserSession } from \"./browser\";\nimport { getDefaultTemplate } from \"./template\";\nimport { computeCacheKey, getCached, writeCache } from \"./cache\";\nimport type {\n OgImageOptions,\n ResolvedOgImageOptions,\n OgImageTemplateProps,\n OgImageTemplateFn,\n} from \"./types\";\n\nexport type {\n OgImageOptions,\n ResolvedOgImageOptions,\n OgImageTemplateProps,\n OgImageTemplateFn,\n} from \"./types\";\n\nexport type { OgBrowserSession } from \"./browser\";\n\n/**\n * Resolves user-provided OG image options with defaults.\n */\nexport function resolveOgImageOptions(options: OgImageOptions | undefined): ResolvedOgImageOptions {\n return {\n template: options?.template,\n vuePlugin: options?.vuePlugin ?? \"vitejs\",\n width: options?.width ?? 1200,\n height: options?.height ?? 630,\n cache: options?.cache ?? true,\n concurrency: options?.concurrency ?? 1,\n };\n}\n\n/**\n * A single page entry for batch OG image generation.\n */\nexport interface OgImagePageEntry {\n /** Props to pass to the template */\n props: OgImageTemplateProps;\n /** Absolute path to write the output PNG */\n outputPath: string;\n}\n\n/**\n * Result of OG image generation for a single page.\n */\nexport interface OgImageResult {\n outputPath: string;\n cached: boolean;\n error?: string;\n}\n\n/**\n * Resolves the template function from options.\n *\n * Dispatches by file extension:\n * - `.vue` → Vue SFC (SSR via vue/server-renderer)\n * - `.svelte` → Svelte SFC (SSR via svelte/server)\n * - `.tsx`/`.jsx` → React Server Component (SSR via react-dom/server)\n * - others → TypeScript template (direct function export)\n */\nasync function resolveTemplate(\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageTemplateFn> {\n if (!options.template) {\n return getDefaultTemplate();\n }\n\n const templatePath = path.resolve(root, options.template);\n\n // Verify file exists\n const fs = await import(\"fs/promises\");\n try {\n await fs.access(templatePath);\n } catch {\n throw new Error(`[ox-content:og-image] Template file not found: ${templatePath}`);\n }\n\n const ext = path.extname(templatePath).toLowerCase();\n\n switch (ext) {\n case \".vue\":\n return resolveVueTemplate(templatePath, options, root);\n case \".svelte\":\n return resolveSvelteTemplate(templatePath, root);\n case \".tsx\":\n case \".jsx\":\n return resolveReactTemplate(templatePath, root);\n default:\n return resolveTsTemplate(templatePath, options, root);\n }\n}\n\n/**\n * Resolves a plain TypeScript template (existing behavior).\n */\nasync function resolveTsTemplate(\n templatePath: string,\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template.mjs\");\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const templateFn = mod.default;\n\n if (typeof templateFn !== \"function\") {\n throw new Error(\n `[ox-content:og-image] Template must default-export a function: ${options.template}`,\n );\n }\n\n return templateFn as OgImageTemplateFn;\n}\n\n/**\n * Resolves a Vue SFC template via SSR.\n *\n * Compiles the SFC with @vue/compiler-sfc (or @vizejs/vite-plugin),\n * bundles with rolldown, then wraps with createSSRApp + renderToString.\n */\nasync function resolveVueTemplate(\n templatePath: string,\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template_vue.mjs\");\n\n const plugins =\n options.vuePlugin === \"vizejs\" ? await getVizejsPlugin() : [createVueCompilerPlugin()];\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n external: [\"vue\", \"vue/server-renderer\"],\n plugins,\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const Component = mod.default;\n\n if (!Component) {\n throw new Error(\n `[ox-content:og-image] Vue template must have a default export: ${templatePath}`,\n );\n }\n\n // Extract CSS from SFC <style> blocks (Vue SSR does not include styles).\n // OG image templates render in complete isolation, so scoping is unnecessary.\n // We use raw CSS content to avoid scope ID mismatches between compilers\n // (e.g., vizejs and @vue/compiler-sfc may produce different scope hashes).\n let extractedCss = ((mod as Record<string, unknown>).__vize_css__ as string) || \"\";\n if (!extractedCss) {\n try {\n let compilerSfc: typeof import(\"@vue/compiler-sfc\");\n try {\n compilerSfc = await import(\"@vue/compiler-sfc\");\n } catch {\n compilerSfc = null as never;\n }\n if (compilerSfc) {\n const sfcSource = await fs.readFile(templatePath, \"utf-8\");\n const { descriptor } = compilerSfc.parse(sfcSource, { filename: templatePath });\n for (const style of descriptor.styles) {\n extractedCss += style.content;\n }\n }\n } catch {\n // CSS extraction is best-effort\n }\n }\n\n // Import Vue SSR utilities\n const { createSSRApp } = await import(\"vue\");\n const { renderToString } = await import(\"vue/server-renderer\");\n\n return async (props) => {\n const app = createSSRApp(Component, props);\n const html = await renderToString(app);\n if (extractedCss) {\n return `<style>${extractedCss}</style>${html}`;\n }\n return html;\n };\n}\n\n/**\n * Creates a rolldown plugin that compiles Vue SFCs using @vue/compiler-sfc.\n */\nfunction createVueCompilerPlugin(): import(\"rolldown\").Plugin {\n return {\n name: \"ox-content-vue-sfc\",\n async transform(code, id) {\n if (!id.endsWith(\".vue\")) return null;\n\n let compilerSfc: typeof import(\"@vue/compiler-sfc\");\n try {\n compilerSfc = await import(\"@vue/compiler-sfc\");\n } catch {\n throw new Error(\n \"[ox-content:og-image] @vue/compiler-sfc is required for .vue templates. \" +\n \"Install it with: pnpm add -D @vue/compiler-sfc\",\n );\n }\n\n const { descriptor } = compilerSfc.parse(code, { filename: id });\n\n // Compile <script setup> or <script>\n let scriptCode: string;\n if (descriptor.scriptSetup || descriptor.script) {\n const compiled = compilerSfc.compileScript(descriptor, {\n id,\n inlineTemplate: true,\n });\n scriptCode = compiled.content;\n } else {\n // Template-only SFC: compile template separately\n if (!descriptor.template) {\n throw new Error(\n `[ox-content:og-image] Vue SFC must have a <template> or <script>: ${id}`,\n );\n }\n const templateResult = compilerSfc.compileTemplate({\n source: descriptor.template.content,\n filename: id,\n id,\n });\n if (templateResult.errors.length > 0) {\n throw new Error(\n `[ox-content:og-image] Vue template compilation errors in ${id}: ${templateResult.errors.map(String).join(\", \")}`,\n );\n }\n scriptCode = `${templateResult.code}\\nexport default { render }`;\n }\n\n // Determine if the compiled output contains TypeScript\n const isTs = !!(descriptor.scriptSetup?.lang === \"ts\" || descriptor.script?.lang === \"ts\");\n\n return { code: scriptCode, moduleType: isTs ? \"ts\" : \"js\" };\n },\n };\n}\n\n/**\n * Loads @vizejs/vite-plugin as a rolldown plugin for Vue SFC compilation.\n */\nasync function getVizejsPlugin(): Promise<import(\"rolldown\").Plugin[]> {\n try {\n const vizejs = await import(\"@vizejs/vite-plugin\");\n const plugin = vizejs.default?.() ?? vizejs;\n return Array.isArray(plugin) ? plugin : [plugin];\n } catch {\n throw new Error(\n \"[ox-content:og-image] @vizejs/vite-plugin is required when vuePlugin is 'vizejs'. \" +\n \"Install it with: pnpm add -D @vizejs/vite-plugin\",\n );\n }\n}\n\n/**\n * Resolves a Svelte SFC template via SSR.\n *\n * Compiles the SFC with svelte/compiler (server mode + runes),\n * bundles with rolldown, then wraps with svelte/server render().\n */\nasync function resolveSvelteTemplate(\n templatePath: string,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template_svelte.mjs\");\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n external: [\"svelte\", \"svelte/server\", \"svelte/internal\", \"svelte/internal/server\"],\n plugins: [createSvelteCompilerPlugin()],\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const Component = mod.default;\n\n if (!Component) {\n throw new Error(\n `[ox-content:og-image] Svelte template must have a default export: ${templatePath}`,\n );\n }\n\n // Import Svelte SSR utility\n const { render } = (await import(\"svelte/server\")) as {\n render: (component: unknown, options: { props: Record<string, unknown> }) => { body: string };\n };\n\n return async (props) => {\n const { body } = render(Component, { props });\n return body;\n };\n}\n\n/**\n * Creates a rolldown plugin that compiles Svelte SFCs using svelte/compiler.\n */\nfunction createSvelteCompilerPlugin(): import(\"rolldown\").Plugin {\n return {\n name: \"ox-content-svelte-sfc\",\n async transform(code, id) {\n if (!id.endsWith(\".svelte\")) return null;\n\n let svelteCompiler: typeof import(\"svelte/compiler\");\n try {\n svelteCompiler = await import(\"svelte/compiler\");\n } catch {\n throw new Error(\n \"[ox-content:og-image] svelte is required for .svelte templates. \" +\n \"Install it with: pnpm add -D svelte\",\n );\n }\n\n const result = svelteCompiler.compile(code, {\n generate: \"server\",\n runes: true,\n filename: id,\n });\n\n return { code: result.js.code };\n },\n };\n}\n\n/**\n * Resolves a React (.tsx/.jsx) template via SSR.\n *\n * Bundles with rolldown (JSX transform), then wraps with\n * react-dom/server renderToReadableStream for async Server Component support.\n */\nasync function resolveReactTemplate(\n templatePath: string,\n root: string,\n): Promise<OgImageTemplateFn> {\n const fs = await import(\"fs/promises\");\n const { rolldown } = await import(\"rolldown\");\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n await fs.mkdir(cacheDir, { recursive: true });\n\n const outfile = path.join(cacheDir, \"_template_react.mjs\");\n\n const bundle = await rolldown({\n input: templatePath,\n platform: \"node\",\n external: [\n \"react\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n \"react-dom\",\n \"react-dom/server\",\n ],\n transform: {\n jsx: \"react-jsx\",\n },\n });\n await bundle.write({\n file: outfile,\n format: \"esm\",\n });\n await bundle.close();\n\n const mod = await import(`${outfile}?t=${Date.now()}`);\n const Component = mod.default;\n\n if (!Component) {\n throw new Error(\n `[ox-content:og-image] React template must have a default export: ${templatePath}`,\n );\n }\n\n // Import React SSR utilities\n let React: typeof import(\"react\");\n let ReactDOMServer: typeof import(\"react-dom/server\");\n try {\n React = await import(\"react\");\n ReactDOMServer = await import(\"react-dom/server\");\n } catch {\n throw new Error(\n \"[ox-content:og-image] react and react-dom are required for .tsx/.jsx templates. \" +\n \"Install them with: pnpm add -D react react-dom\",\n );\n }\n\n return async (props) => {\n const element = React.createElement(Component, props);\n // Use renderToReadableStream for async Server Component support\n const stream = await ReactDOMServer.renderToReadableStream(element);\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n const decoder = new TextDecoder();\n return (\n chunks.map((chunk) => decoder.decode(chunk, { stream: true })).join(\"\") + decoder.decode()\n );\n };\n}\n\n/**\n * Computes a stable template source identifier for cache keys.\n *\n * For custom templates, hashes the file content so cache invalidates\n * when the template changes. For the default template, returns a fixed string.\n */\nasync function computeTemplateSource(\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<string> {\n if (!options.template) {\n return \"__default__\";\n }\n\n const fs = await import(\"fs/promises\");\n const templatePath = path.resolve(root, options.template);\n const content = await fs.readFile(templatePath, \"utf-8\");\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n/**\n * Generates OG images for a batch of pages.\n *\n * Manages the full lifecycle: resolve template → launch browser (with `using`) →\n * render each page (with caching and concurrency).\n *\n * All errors are non-fatal: failures are reported in results but never throw.\n */\nexport async function generateOgImages(\n pages: OgImagePageEntry[],\n options: ResolvedOgImageOptions,\n root: string,\n): Promise<OgImageResult[]> {\n if (pages.length === 0) return [];\n\n // Resolve template\n const templateFn = await resolveTemplate(options, root);\n\n // Compute template source for cache key\n const templateSource = await computeTemplateSource(options, root);\n\n // Cache directory\n const cacheDir = path.join(root, \".cache\", \"og-images\");\n\n // Try to serve all from cache first if caching is enabled\n if (options.cache) {\n const allCached = await tryServeAllFromCache(pages, templateSource, options, cacheDir);\n if (allCached) return allCached;\n }\n\n // Launch browser\n await using session = await openBrowser();\n if (!session) {\n return pages.map((p) => ({\n outputPath: p.outputPath,\n cached: false,\n error: \"Chromium not available\",\n }));\n }\n\n const results: OgImageResult[] = [];\n\n // Resolve public directory for serving local assets in templates\n const publicDir = path.join(root, \"public\");\n\n // Process pages with concurrency control\n const concurrency = Math.max(1, options.concurrency);\n\n for (let i = 0; i < pages.length; i += concurrency) {\n const batch = pages.slice(i, i + concurrency);\n const batchResults = await Promise.all(\n batch.map((entry) =>\n renderSinglePage(entry, templateFn, templateSource, options, cacheDir, session, publicDir),\n ),\n );\n results.push(...batchResults);\n }\n\n return results;\n}\n\n/**\n * Tries to serve all pages from cache.\n * Returns results if ALL pages are cached, null otherwise.\n */\nasync function tryServeAllFromCache(\n pages: OgImagePageEntry[],\n templateSource: string,\n options: ResolvedOgImageOptions,\n cacheDir: string,\n): Promise<OgImageResult[] | null> {\n const fs = await import(\"fs/promises\");\n const results: OgImageResult[] = [];\n\n for (const entry of pages) {\n const key = computeCacheKey(\n templateSource,\n entry.props as unknown as Record<string, unknown>,\n options.width,\n options.height,\n );\n const cached = await getCached(cacheDir, key);\n if (!cached) return null; // At least one miss, need browser\n\n // Write cached file to output\n await fs.mkdir(path.dirname(entry.outputPath), { recursive: true });\n await fs.writeFile(entry.outputPath, cached);\n results.push({ outputPath: entry.outputPath, cached: true });\n }\n\n return results;\n}\n\n/**\n * Renders a single page to PNG, with cache support.\n */\nasync function renderSinglePage(\n entry: OgImagePageEntry,\n templateFn: OgImageTemplateFn,\n templateSource: string,\n options: ResolvedOgImageOptions,\n cacheDir: string,\n session: OgBrowserSession,\n publicDir?: string,\n): Promise<OgImageResult> {\n const fs = await import(\"fs/promises\");\n\n try {\n // Check cache\n if (options.cache) {\n const key = computeCacheKey(\n templateSource,\n entry.props as unknown as Record<string, unknown>,\n options.width,\n options.height,\n );\n const cached = await getCached(cacheDir, key);\n if (cached) {\n await fs.mkdir(path.dirname(entry.outputPath), { recursive: true });\n await fs.writeFile(entry.outputPath, cached);\n return { outputPath: entry.outputPath, cached: true };\n }\n }\n\n // Render template to HTML (may be async for SFC templates)\n const html = await templateFn(entry.props);\n\n // Render HTML to PNG via session (page create/close handled internally)\n const png = await session.renderPage(html, options.width, options.height, publicDir);\n\n // Write output\n await fs.mkdir(path.dirname(entry.outputPath), { recursive: true });\n await fs.writeFile(entry.outputPath, png);\n\n // Write cache\n if (options.cache) {\n const key = computeCacheKey(\n templateSource,\n entry.props as unknown as Record<string, unknown>,\n options.width,\n options.height,\n );\n await writeCache(cacheDir, key, png);\n }\n\n return { outputPath: entry.outputPath, cached: false };\n } catch (err) {\n return {\n outputPath: entry.outputPath,\n cached: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * Island Parser\n *\n * Detects <Island> components in HTML and transforms them\n * into hydration-ready elements with data attributes.\n */\n\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeStringify from \"rehype-stringify\";\nimport type { Root, Element } from \"hast\";\n\nexport type LoadStrategy = \"eager\" | \"idle\" | \"visible\" | \"media\";\n\nexport interface IslandInfo {\n component: string;\n load: LoadStrategy;\n mediaQuery?: string;\n props: Record<string, unknown>;\n}\n\nexport interface ParseIslandsResult {\n html: string;\n islands: IslandInfo[];\n}\n\n/**\n * Get element attribute value.\n */\nfunction getAttribute(el: Element, name: string): string | undefined {\n const value = el.properties?.[name];\n if (typeof value === \"string\") return value;\n if (Array.isArray(value)) return value.join(\" \");\n return undefined;\n}\n\n/**\n * Parse JSX-style props from attributes.\n */\nfunction parseProps(el: Element): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n\n if (!el.properties) return props;\n\n for (const [key, value] of Object.entries(el.properties)) {\n // Skip special attributes\n if ([\"load\", \"media\", \"className\", \"class\"].includes(key)) continue;\n\n // Handle JSX-style props like {0} or {true}\n if (typeof value === \"string\") {\n // Try to parse as JSON/JS value if it looks like one\n const trimmed = value.trim();\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n const inner = trimmed.slice(1, -1);\n try {\n // Try JSON parse first\n props[key] = JSON.parse(inner);\n } catch {\n // Try evaluating simple expressions\n if (inner === \"true\") props[key] = true;\n else if (inner === \"false\") props[key] = false;\n else if (inner === \"null\") props[key] = null;\n else if (!Number.isNaN(Number(inner))) props[key] = Number(inner);\n else props[key] = value;\n }\n } else {\n props[key] = value;\n }\n } else if (typeof value === \"number\" || typeof value === \"boolean\") {\n props[key] = value;\n } else if (Array.isArray(value)) {\n props[key] = value;\n }\n }\n\n return props;\n}\n\n/**\n * Find the component element inside <Island>.\n */\nfunction findComponentElement(children: Element[\"children\"]): Element | null {\n for (const child of children) {\n if (child.type === \"element\") {\n // Skip text/whitespace, look for actual component\n if (child.tagName !== \"br\" && child.tagName !== \"span\") {\n return child;\n }\n }\n }\n return null;\n}\n\n/**\n * Get component name from child element.\n */\nfunction getComponentName(el: Element): string {\n // PascalCase tag names are components\n const tagName = el.tagName;\n if (tagName && /^[A-Z]/.test(tagName)) {\n return tagName;\n }\n // Check for data-component attribute\n return getAttribute(el, \"data-component\") || tagName;\n}\n\nlet islandCounter = 0;\n\n/**\n * Reset island counter (for testing).\n */\nexport function resetIslandCounter(): void {\n islandCounter = 0;\n}\n\n/**\n * Rehype plugin to transform Island components.\n */\nfunction rehypeIslands(collectedIslands: IslandInfo[]) {\n return (tree: Root) => {\n const visit = (node: Root | Element) => {\n if (\"children\" in node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n\n if (child.type === \"element\") {\n // Check for <Island> component\n if (child.tagName.toLowerCase() === \"island\") {\n const load = (getAttribute(child, \"load\") as LoadStrategy) || \"eager\";\n const mediaQuery = getAttribute(child, \"media\");\n\n // Find the component inside\n const componentEl = findComponentElement(child.children);\n\n if (componentEl) {\n const componentName = getComponentName(componentEl);\n const componentProps = parseProps(componentEl);\n\n // Collect island info\n const islandInfo: IslandInfo = {\n component: componentName,\n load,\n mediaQuery,\n props: componentProps,\n };\n collectedIslands.push(islandInfo);\n\n // Create island wrapper with data attributes\n const islandId = `ox-island-${islandCounter++}`;\n\n const islandElement: Element = {\n type: \"element\",\n tagName: \"div\",\n properties: {\n id: islandId,\n \"data-ox-island\": componentName,\n \"data-ox-load\": load,\n ...(mediaQuery && { \"data-ox-media\": mediaQuery }),\n \"data-ox-props\": JSON.stringify(componentProps),\n className: [\"ox-island\"],\n },\n children: [\n // Keep original content as fallback/placeholder\n ...componentEl.children,\n ],\n };\n\n node.children[i] = islandElement;\n }\n } else {\n visit(child);\n }\n }\n }\n }\n };\n\n visit(tree);\n };\n}\n\n/**\n * Transform Island components in HTML.\n *\n * Converts:\n * ```html\n * <Island load=\"visible\">\n * <Counter initial={0} />\n * </Island>\n * ```\n *\n * To:\n * ```html\n * <div id=\"ox-island-0\"\n * data-ox-island=\"Counter\"\n * data-ox-load=\"visible\"\n * data-ox-props='{\"initial\":0}'\n * class=\"ox-island\">\n * <!-- fallback content -->\n * </div>\n * ```\n */\nexport async function transformIslands(html: string): Promise<ParseIslandsResult> {\n const islands: IslandInfo[] = [];\n\n const result = await unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeIslands, islands)\n .use(rehypeStringify)\n .process(html);\n\n return {\n html: String(result),\n islands,\n };\n}\n\n/**\n * Check if HTML contains any Island components.\n */\nexport function hasIslands(html: string): boolean {\n return /<island[\\s>]/i.test(html);\n}\n\n/**\n * Extract island info without transforming HTML.\n * Useful for analysis/bundling purposes.\n */\nexport async function extractIslandInfo(html: string): Promise<IslandInfo[]> {\n const { islands } = await transformIslands(html);\n return islands;\n}\n\n/**\n * Generate client-side hydration script.\n * This is a minimal script that imports and initializes islands.\n */\nexport function generateHydrationScript(components: string[]): string {\n if (components.length === 0) return \"\";\n\n const imports = components.map((name) => `import ${name} from './${name}';`).join(\"\\n\");\n\n return `\nimport { initIslands } from '@ox-content/islands';\n${imports}\n\nconst components = {\n ${components.join(\",\\n \")}\n};\n\n// Initialize with your framework's hydration\n// This example uses Vue, adapt for React/Svelte/etc.\nimport { createApp, h } from 'vue';\n\ninitIslands((el, props) => {\n const name = el.dataset.oxIsland;\n const Component = components[name];\n if (!Component) {\n console.warn(\\`[ox-islands] Unknown component: \\${name}\\`);\n return;\n }\n\n const app = createApp({ render: () => h(Component, props) });\n app.mount(el);\n\n return () => app.unmount();\n});\n`;\n}\n","/**\n * SSG (Static Site Generation) module for ox-content\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { transformMarkdown } from \"./transform\";\nimport { generateOgImages } from \"./og-image\";\nimport type { OgImagePageEntry } from \"./og-image\";\nimport { transformAllPlugins } from \"./plugins\";\nimport type { TransformAllOptions } from \"./plugins\";\nimport { protectMermaidSvgs, restoreMermaidSvgs } from \"./plugins/mermaid-protect\";\nimport { transformIslands, hasIslands } from \"./island\";\nimport { importNapiModule, importNapiModuleSync } from \"./napi\";\nimport { DEFAULT_MARKDOWN_EXTENSIONS } from \"./markdown\";\nimport type {\n ResolvedOptions,\n ResolvedSsgOptions,\n SsgOptions,\n SsgNavigationGroup,\n TocEntry,\n HeroConfig,\n FeatureConfig,\n LocaleConfig,\n} from \"./types\";\nimport { resolveTheme, themeToNapi } from \"./theme\";\nimport type { ResolvedThemeConfig, SidebarItem } from \"./theme\";\nimport { normalizeVitePressFrontmatter } from \"./vitepress\";\n\n/**\n * Navigation item for SSG.\n */\nexport interface SsgNavItem {\n title: string;\n path: string;\n href: string;\n children?: SsgNavItem[];\n collapsed?: boolean;\n}\n\n/**\n * Entry page configuration for SSG (passed to Rust).\n */\nexport interface SsgEntryPageConfig {\n hero?: HeroConfig;\n features?: FeatureConfig[];\n}\n\n/**\n * Page data for SSG.\n */\nexport interface SsgPageData {\n title: string;\n description?: string;\n content: string;\n toc: TocEntry[];\n lastUpdated?: number;\n frontmatter: Record<string, unknown>;\n path: string;\n href: string;\n /** Entry page configuration (if layout: entry) */\n entryPage?: SsgEntryPageConfig;\n}\n\ninterface SsgRoutePaths {\n outputPath: string;\n urlPath: string;\n href: string;\n ogImagePath: string;\n ogImageUrl: string;\n}\n\n/**\n * Deprecated compatibility export for consumers that imported the former\n * TypeScript SSG template. HTML generation is Rust-backed now.\n *\n * @deprecated Use `generateHtmlPage`/`buildSsg` instead.\n */\nexport const DEFAULT_HTML_TEMPLATE = \"<!-- ox-content default HTML template is Rust-backed -->\";\n\n/**\n * Resolves SSG options with defaults.\n */\nexport function resolveSsgOptions(ssg: SsgOptions | boolean | undefined): ResolvedSsgOptions {\n if (ssg === false) {\n return {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n lastUpdated: false,\n };\n }\n\n if (ssg === true || ssg === undefined) {\n return {\n enabled: true,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n lastUpdated: false,\n theme: resolveTheme(undefined),\n };\n }\n\n return {\n enabled: ssg.enabled ?? true,\n extension: ssg.extension ?? \".html\",\n clean: ssg.clean ?? false,\n bare: ssg.bare ?? false,\n siteName: ssg.siteName,\n ogImage: ssg.ogImage,\n generateOgImage: ssg.generateOgImage ?? false,\n lastUpdated: ssg.lastUpdated ?? false,\n siteUrl: ssg.siteUrl,\n theme: resolveTheme(ssg.theme),\n navigation: ssg.navigation,\n };\n}\n\n/**\n * Extracts title from content or frontmatter.\n */\nexport function extractTitle(content: string, frontmatter: Record<string, unknown>): string {\n return importNapiModuleSync().extractSsgTitle(\n content,\n typeof frontmatter.title === \"string\" ? frontmatter.title : undefined,\n );\n}\n\n/**\n * Generates bare HTML page (no navigation, no styles).\n */\nexport function generateBareHtmlPage(content: string, title: string): string {\n return importNapiModuleSync().generateSsgBareHtml(content, title);\n}\n\n/** NAPI-facing nav group shape produced from a [`NavGroup`]. */\ninterface RustNavGroup {\n title: string;\n collapsed?: boolean;\n items: SsgNavItem[];\n}\n\n/**\n * Per-build cache for the Rust-facing nav conversion. `navGroups` is the same\n * `context.navItems` reference for every page in a build, so the deep recursive\n * copy below only needs to run once per build instead of once per page.\n */\nconst navGroupsForRustCache = new WeakMap<NavGroup[], RustNavGroup[]>();\n\nfunction toRustNavItem(item: SsgNavItem): SsgNavItem {\n return {\n title: item.title,\n path: item.path,\n href: item.href,\n children: item.children?.map(toRustNavItem),\n collapsed: item.collapsed,\n };\n}\n\nfunction convertNavGroupsForRust(navGroups: NavGroup[]): RustNavGroup[] {\n const cached = navGroupsForRustCache.get(navGroups);\n if (cached) {\n return cached;\n }\n const converted = navGroups.map((group) => ({\n title: group.title,\n collapsed: group.collapsed,\n items: group.items.map(toRustNavItem),\n }));\n navGroupsForRustCache.set(navGroups, converted);\n return converted;\n}\n\n/**\n * Converts a `TocEntry` tree into the plain shape the Rust binding expects.\n * Hoisted to module scope so it isn't reallocated for every page; the\n * per-page `.map` over `pageData.toc` still runs since the TOC is page-specific.\n */\nfunction toRustTocEntry(entry: TocEntry): TocEntry {\n return {\n depth: entry.depth,\n text: entry.text,\n slug: entry.slug,\n children: entry.children?.map(toRustTocEntry) ?? [],\n };\n}\n\n/** Rust-facing locale shape. */\ninterface RustLocale {\n code: string;\n name: string;\n dir: string;\n}\n\n/**\n * Per-build cache for the Rust-facing locale list. `i18n.locales` is the same\n * reference for every page in a build, so this mapping (and the `?? \"ltr\"`\n * default) only runs once per build instead of once per page.\n */\nconst rustLocalesCache = new WeakMap<LocaleConfig[], RustLocale[]>();\n\nfunction toRustLocales(locales: LocaleConfig[]): RustLocale[] {\n const cached = rustLocalesCache.get(locales);\n if (cached) {\n return cached;\n }\n const converted = locales.map((locale) => ({\n code: locale.code,\n name: locale.name,\n dir: locale.dir ?? \"ltr\",\n }));\n rustLocalesCache.set(locales, converted);\n return converted;\n}\n\n/**\n * Per-build cache for the locale-code list passed to `getSsgPageLocale`. The\n * `i18n.locales` reference is stable across a build, so the `.map` to codes\n * runs once instead of once per page.\n */\nconst localeCodesCache = new WeakMap<LocaleConfig[], string[]>();\n\nfunction localeCodesFor(locales: LocaleConfig[]): string[] {\n const cached = localeCodesCache.get(locales);\n if (cached) {\n return cached;\n }\n const codes = locales.map((locale) => locale.code);\n localeCodesCache.set(locales, codes);\n return codes;\n}\n\n/**\n * Generates HTML page with navigation using Rust NAPI bindings.\n */\nexport async function generateHtmlPage(\n pageData: SsgPageData,\n navGroups: NavGroup[],\n siteName: string,\n base: string,\n ogImage?: string,\n theme?: ResolvedThemeConfig,\n locale?: string,\n availableLocales?: LocaleConfig[],\n): Promise<string> {\n const mod = await importNapiModule();\n\n // Convert TocEntry to the format expected by Rust (converter is module-scoped).\n const tocForRust = pageData.toc.map(toRustTocEntry);\n\n // Convert NavGroup to the format expected by Rust (cached per build).\n const navGroupsForRust = convertNavGroupsForRust(navGroups);\n\n // Convert theme to NAPI format if provided\n const themeForRust = theme ? themeToNapi(theme) : undefined;\n\n // Convert entry page to NAPI format if provided\n const entryPageForRust = pageData.entryPage\n ? {\n hero: pageData.entryPage.hero\n ? {\n name: pageData.entryPage.hero.name,\n text: pageData.entryPage.hero.text,\n tagline: pageData.entryPage.hero.tagline,\n notice: pageData.entryPage.hero.notice\n ? {\n title: pageData.entryPage.hero.notice.title,\n body: pageData.entryPage.hero.notice.body,\n }\n : undefined,\n image: pageData.entryPage.hero.image\n ? {\n src: pageData.entryPage.hero.image.src,\n lightSrc: pageData.entryPage.hero.image.lightSrc,\n darkSrc: pageData.entryPage.hero.image.darkSrc,\n alt: pageData.entryPage.hero.image.alt,\n width: pageData.entryPage.hero.image.width,\n height: pageData.entryPage.hero.image.height,\n }\n : undefined,\n actions: pageData.entryPage.hero.actions?.map((a) => ({\n theme: a.theme,\n text: a.text,\n link: a.link,\n })),\n }\n : undefined,\n features: pageData.entryPage.features?.map((f) => ({\n icon: f.icon,\n title: f.title,\n details: f.details,\n link: f.link,\n linkText: f.linkText,\n })),\n }\n : undefined;\n\n return mod.generateSsgHtml(\n {\n title: pageData.title,\n description: pageData.description,\n content: pageData.content,\n toc: tocForRust,\n lastUpdated: pageData.lastUpdated,\n path: pageData.path,\n entryPage: entryPageForRust,\n },\n navGroupsForRust,\n {\n siteName,\n base,\n ogImage,\n theme: themeForRust,\n locale,\n availableLocales: availableLocales ? toRustLocales(availableLocales) : undefined,\n },\n );\n}\n\ninterface GeneratedHtmlPage {\n inputPath: string;\n outputPath: string;\n html: string;\n}\n\ninterface ExternalizedSharedAsset {\n outputPath: string;\n content: string;\n}\n\nasync function externalizeSharedPageAssets(\n pages: GeneratedHtmlPage[],\n outDir: string,\n base: string,\n): Promise<{ pages: GeneratedHtmlPage[]; assets: string[] }> {\n const mod = await importNapiModule();\n const optimized = mod.externalizeSsgAssets(pages, outDir, base) as {\n pages: GeneratedHtmlPage[];\n assets: ExternalizedSharedAsset[];\n };\n\n await Promise.all(\n optimized.assets.map(async (asset) => {\n await fs.mkdir(path.dirname(asset.outputPath), { recursive: true });\n await fs.writeFile(asset.outputPath, asset.content, \"utf-8\");\n }),\n );\n\n return {\n pages: optimized.pages,\n assets: optimized.assets.map((asset) => asset.outputPath),\n };\n}\n\n/**\n * Converts a markdown file path to its corresponding HTML output path.\n */\nexport function getOutputPath(\n inputPath: string,\n srcDir: string,\n outDir: string,\n extension: string,\n): string {\n return importNapiModuleSync().getSsgOutputPath(inputPath, srcDir, outDir, extension);\n}\n\n/**\n * Converts a markdown file path to a relative URL path.\n */\nexport function getUrlPath(inputPath: string, srcDir: string): string {\n return importNapiModuleSync().getSsgUrlPath(inputPath, srcDir);\n}\n\n/**\n * Converts a markdown file path to an href.\n */\nexport function getHref(\n inputPath: string,\n srcDir: string,\n base: string,\n extension: string,\n): string {\n return importNapiModuleSync().getSsgHref(inputPath, srcDir, base, extension);\n}\n\n/**\n * Resolves manual navigation config to the format used by the built-in SSG renderer.\n */\nexport function resolveNavigationGroups(\n navigation: SsgNavigationGroup[] | undefined,\n base: string,\n extension: string,\n): NavGroup[] | undefined {\n if (!navigation) {\n return undefined;\n }\n\n return importNapiModuleSync().resolveSsgNavigationGroups(navigation, base, extension);\n}\n\nexport function getPageLocale(urlPath: string, i18n: ResolvedOptions[\"i18n\"]): string | undefined {\n if (!i18n) return undefined;\n return (\n importNapiModuleSync().getSsgPageLocale(\n urlPath,\n i18n.defaultLocale,\n localeCodesFor(i18n.locales),\n ) ?? undefined\n );\n}\n\nfunction getRoutePaths(\n inputPath: string,\n srcDir: string,\n outDir: string,\n base: string,\n extension: string,\n siteUrl?: string,\n): SsgRoutePaths {\n return importNapiModuleSync().resolveSsgRoutePaths(\n inputPath,\n srcDir,\n outDir,\n base,\n extension,\n siteUrl,\n );\n}\n\n/**\n * Formats a file/dir name as a title.\n */\nexport function formatTitle(name: string): string {\n return importNapiModuleSync().formatSsgTitle(name);\n}\n\n/**\n * Collects all markdown files from the source directory.\n */\nexport async function collectMarkdownFiles(\n srcDir: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): Promise<string[]> {\n return importNapiModuleSync().collectSsgMarkdownFiles(srcDir, [...extensions]);\n}\n\n/**\n * Navigation group for hierarchical navigation.\n */\nexport interface NavGroup {\n title: string;\n items: SsgNavItem[];\n collapsed?: boolean;\n}\n\n/**\n * Builds navigation items from markdown files, grouped by directory.\n */\nexport function buildNavItems(\n markdownFiles: string[],\n srcDir: string,\n base: string,\n extension: string,\n): NavGroup[] {\n return importNapiModuleSync().buildSsgNavItems(markdownFiles, srcDir, base, extension);\n}\n\n/**\n * Builds navigation items from an explicit theme sidebar tree.\n */\nexport function buildThemeNavItems(\n sidebar: SidebarItem[],\n base: string,\n extension: string,\n): NavGroup[] {\n return importNapiModuleSync().buildSsgThemeNavItems(sidebar, base, extension);\n}\n\ninterface BuildSsgContext {\n options: ResolvedOptions;\n ssgOptions: ResolvedSsgOptions;\n root: string;\n srcDir: string;\n outDir: string;\n base: string;\n siteName: string;\n navItems: NavGroup[];\n shouldGenerateOgImages: boolean;\n napi?: Awaited<ReturnType<typeof importNapiModule>>;\n}\n\ninterface PageProcessResult {\n inputPath: string;\n routePaths: SsgRoutePaths;\n transformedHtml: string;\n title: string;\n description?: string;\n lastUpdated?: number;\n frontmatter: Record<string, unknown>;\n toc: TocEntry[];\n}\n\ninterface CollectedPageResults {\n pageResults: PageProcessResult[];\n ogImageEntries: OgImagePageEntry[];\n ogImageInputPaths: string[];\n ogImageUrlMap: Map<string, string>;\n errors: string[];\n}\n\n/**\n * Builds all markdown files to static HTML.\n */\nexport async function buildSsg(\n options: ResolvedOptions,\n root: string,\n): Promise<{ files: string[]; errors: string[] }> {\n const ssgOptions = options.ssg;\n if (!ssgOptions.enabled) {\n return { files: [], errors: [] };\n }\n\n const srcDir = path.resolve(root, options.srcDir);\n const outDir = path.resolve(root, options.outDir);\n const generatedFiles: string[] = [];\n const errors: string[] = [];\n\n await cleanOutputDirectory(ssgOptions, outDir);\n\n const markdownFiles = await collectMarkdownFiles(srcDir, options.extensions);\n const context = await createBuildSsgContext(options, root, srcDir, outDir, markdownFiles);\n const collected = await collectPageResults(context, markdownFiles);\n errors.push(...collected.errors);\n\n await generateOgImageAssets(context, collected, generatedFiles, errors);\n\n const generatedPages = await generateHtmlPages(context, collected.pageResults, collected, errors);\n await writeGeneratedPages(generatedPages, context, generatedFiles);\n\n return { files: generatedFiles, errors };\n}\n\nasync function cleanOutputDirectory(ssgOptions: ResolvedSsgOptions, outDir: string): Promise<void> {\n if (!ssgOptions.clean) {\n return;\n }\n\n try {\n await fs.rm(outDir, { recursive: true, force: true });\n } catch {\n // Ignore if directory doesn't exist.\n }\n}\n\nasync function createBuildSsgContext(\n options: ResolvedOptions,\n root: string,\n srcDir: string,\n outDir: string,\n markdownFiles: string[],\n): Promise<BuildSsgContext> {\n const ssgOptions = options.ssg;\n const base = options.base.endsWith(\"/\") ? options.base : options.base + \"/\";\n const navItems =\n resolveNavigationGroups(ssgOptions.navigation, base, ssgOptions.extension) ??\n (ssgOptions.theme?.sidebar.length\n ? buildThemeNavItems(ssgOptions.theme.sidebar, base, ssgOptions.extension)\n : buildNavItems(markdownFiles, srcDir, base, ssgOptions.extension));\n\n return {\n options,\n ssgOptions,\n root,\n srcDir,\n outDir,\n base,\n navItems,\n siteName: await resolveSiteName(root, ssgOptions),\n shouldGenerateOgImages: (options.ogImage || ssgOptions.generateOgImage) && !ssgOptions.bare,\n napi: ssgOptions.lastUpdated ? await importNapiModule() : undefined,\n };\n}\n\nasync function resolveSiteName(root: string, ssgOptions: ResolvedSsgOptions): Promise<string> {\n if (ssgOptions.siteName) {\n return ssgOptions.siteName;\n }\n\n try {\n const pkgPath = path.join(root, \"package.json\");\n const pkg = JSON.parse(await fs.readFile(pkgPath, \"utf-8\"));\n return pkg.name ? formatTitle(pkg.name) : \"Documentation\";\n } catch {\n return \"Documentation\";\n }\n}\n\nasync function collectPageResults(\n context: BuildSsgContext,\n markdownFiles: string[],\n): Promise<CollectedPageResults> {\n const collected: CollectedPageResults = {\n pageResults: [],\n ogImageEntries: [],\n ogImageInputPaths: [],\n ogImageUrlMap: new Map(),\n errors: [],\n };\n\n for (const inputPath of markdownFiles) {\n try {\n const pageResult = await transformSsgPage(context, inputPath);\n collected.pageResults.push(pageResult);\n collectOgImageEntry(context, pageResult, collected);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n collected.errors.push(`Failed to process ${inputPath}: ${errorMessage}`);\n }\n }\n\n return collected;\n}\n\nasync function transformSsgPage(\n context: BuildSsgContext,\n inputPath: string,\n): Promise<PageProcessResult> {\n const content = await fs.readFile(inputPath, \"utf-8\");\n const result = await transformMarkdown(content, inputPath, context.options, {\n convertMdLinks: true,\n baseUrl: context.base,\n sourcePath: inputPath,\n });\n const frontmatter = normalizeVitePressFrontmatter(result.frontmatter);\n const transformedHtml = await transformSsgHtml(result.html, context.options);\n const title = extractTitle(transformedHtml, frontmatter);\n\n return {\n inputPath,\n routePaths: getRoutePaths(\n inputPath,\n context.srcDir,\n context.outDir,\n context.base,\n context.ssgOptions.extension,\n context.ssgOptions.siteUrl,\n ),\n transformedHtml,\n title,\n description: frontmatter.description as string | undefined,\n lastUpdated: context.napi?.getGitLastUpdated(inputPath, context.root) ?? undefined,\n frontmatter,\n toc: result.toc,\n };\n}\n\nasync function transformSsgHtml(html: string, options: ResolvedOptions): Promise<string> {\n const { html: protectedHtml, svgs: mermaidSvgs } = protectMermaidSvgs(html);\n const pluginOptions: TransformAllOptions = {\n tabs: true,\n youtube: true,\n github: options.embeds.github,\n openGraph: options.embeds.openGraph,\n pm: options.embeds.pm,\n spotify: options.embeds.spotify,\n stackBlitz: options.embeds.stackBlitz,\n twitter: options.embeds.twitter,\n bluesky: options.embeds.bluesky,\n webContainer: options.embeds.webContainer,\n mermaid: true,\n githubToken: process.env.GITHUB_TOKEN,\n };\n\n let transformedHtml = await transformAllPlugins(protectedHtml, pluginOptions);\n if (hasIslands(transformedHtml)) {\n const islandResult = await transformIslands(transformedHtml);\n transformedHtml = islandResult.html;\n }\n\n return restoreMermaidSvgs(transformedHtml, mermaidSvgs);\n}\n\nfunction collectOgImageEntry(\n context: BuildSsgContext,\n pageResult: PageProcessResult,\n collected: CollectedPageResults,\n): void {\n if (!context.shouldGenerateOgImages) {\n return;\n }\n\n const { layout: _layout, ...frontmatterRest } = pageResult.frontmatter;\n collected.ogImageEntries.push({\n props: {\n ...frontmatterRest,\n title: pageResult.title,\n description: pageResult.description,\n siteName: context.siteName,\n },\n outputPath: pageResult.routePaths.ogImagePath,\n });\n collected.ogImageInputPaths.push(pageResult.inputPath);\n collected.ogImageUrlMap.set(pageResult.inputPath, pageResult.routePaths.ogImageUrl);\n}\n\nasync function generateOgImageAssets(\n context: BuildSsgContext,\n collected: CollectedPageResults,\n generatedFiles: string[],\n errors: string[],\n): Promise<void> {\n if (!context.shouldGenerateOgImages || collected.ogImageEntries.length === 0) {\n return;\n }\n\n try {\n const ogResults = await generateOgImages(\n collected.ogImageEntries,\n context.options.ogImageOptions,\n context.root,\n );\n if (clearMissingBrowserOgImages(ogResults, collected)) {\n return;\n }\n\n reportOgImageResults(ogResults, collected, generatedFiles, errors);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n console.warn(`[ox-content:og-image] Batch generation failed: ${errorMessage}`);\n collected.ogImageUrlMap.clear();\n }\n}\n\nfunction clearMissingBrowserOgImages(\n ogResults: Awaited<ReturnType<typeof generateOgImages>>,\n collected: CollectedPageResults,\n): boolean {\n const allMissingBrowser =\n ogResults.length > 0 && ogResults.every((result) => result.error === \"Chromium not available\");\n if (!allMissingBrowser) {\n return false;\n }\n\n for (const inputPath of collected.ogImageInputPaths) {\n collected.ogImageUrlMap.delete(inputPath);\n }\n return true;\n}\n\nfunction reportOgImageResults(\n ogResults: Awaited<ReturnType<typeof generateOgImages>>,\n collected: CollectedPageResults,\n generatedFiles: string[],\n errors: string[],\n): void {\n let ogSuccessCount = 0;\n\n for (let i = 0; i < ogResults.length; i++) {\n const result = ogResults[i];\n if (result.error) {\n errors.push(`OG image failed for ${result.outputPath}: ${result.error}`);\n collected.ogImageUrlMap.delete(collected.ogImageInputPaths[i]);\n } else {\n generatedFiles.push(result.outputPath);\n ogSuccessCount++;\n }\n }\n\n if (ogSuccessCount > 0) {\n const cachedCount = ogResults.filter((result) => result.cached && !result.error).length;\n console.log(\n `[ox-content:og-image] Generated ${ogSuccessCount} OG images` +\n (cachedCount > 0 ? ` (${cachedCount} from cache)` : \"\"),\n );\n }\n}\n\nasync function generateHtmlPages(\n context: BuildSsgContext,\n pageResults: PageProcessResult[],\n collected: CollectedPageResults,\n errors: string[],\n): Promise<GeneratedHtmlPage[]> {\n const generatedPages: GeneratedHtmlPage[] = [];\n\n for (const pageResult of pageResults) {\n try {\n generatedPages.push({\n inputPath: pageResult.inputPath,\n outputPath: pageResult.routePaths.outputPath,\n html: await renderSsgPage(context, pageResult, collected.ogImageUrlMap),\n });\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n errors.push(`Failed to generate HTML for ${pageResult.inputPath}: ${errorMessage}`);\n }\n }\n\n return generatedPages;\n}\n\nasync function renderSsgPage(\n context: BuildSsgContext,\n pageResult: PageProcessResult,\n ogImageUrlMap: Map<string, string>,\n): Promise<string> {\n if (context.ssgOptions.bare) {\n return generateBareHtmlPage(pageResult.transformedHtml, pageResult.title);\n }\n\n const pageData = createSsgPageData(pageResult);\n const pageOgImage =\n context.shouldGenerateOgImages && ogImageUrlMap.has(pageResult.inputPath)\n ? ogImageUrlMap.get(pageResult.inputPath)\n : context.ssgOptions.ogImage;\n\n return generateHtmlPage(\n pageData,\n context.navItems,\n context.siteName,\n context.base,\n pageOgImage,\n context.ssgOptions.theme,\n getPageLocale(pageData.path, context.options.i18n),\n context.options.i18n ? context.options.i18n.locales : undefined,\n );\n}\n\nfunction createSsgPageData(pageResult: PageProcessResult): SsgPageData {\n const { frontmatter } = pageResult;\n const entryPage =\n frontmatter.layout === \"entry\"\n ? {\n hero: frontmatter.hero as HeroConfig | undefined,\n features: frontmatter.features as FeatureConfig[] | undefined,\n }\n : undefined;\n\n return {\n title: pageResult.title,\n description: pageResult.description,\n content: pageResult.transformedHtml,\n toc: pageResult.toc,\n lastUpdated: pageResult.lastUpdated,\n frontmatter,\n path: pageResult.routePaths.urlPath,\n href: pageResult.routePaths.href,\n entryPage,\n };\n}\n\nasync function writeGeneratedPages(\n generatedPages: GeneratedHtmlPage[],\n context: BuildSsgContext,\n generatedFiles: string[],\n): Promise<void> {\n const optimizedOutput = await externalizeSharedPageAssets(\n generatedPages,\n context.outDir,\n context.base,\n );\n generatedFiles.push(...optimizedOutput.assets);\n\n for (const page of optimizedOutput.pages) {\n await fs.mkdir(path.dirname(page.outputPath), { recursive: true });\n await fs.writeFile(page.outputPath, page.html, \"utf-8\");\n generatedFiles.push(page.outputPath);\n }\n}\n","/**\n * Full-text search functionality for Ox Content.\n *\n * Generates search index at build time and provides client-side search.\n */\n\nimport { importNapiModule, importNapiModuleSync } from \"./napi\";\nimport { DEFAULT_MARKDOWN_EXTENSIONS } from \"./markdown\";\nimport type {\n SearchOptions,\n ResolvedSearchOptions,\n SearchDocument,\n ScopedSearchQuery,\n} from \"./types\";\n\n// Import Rust bindings\nlet oxContent: typeof import(\"@ox-content/napi\") | null = null;\n\nasync function getOxContent() {\n if (!oxContent) {\n try {\n oxContent = await importNapiModule();\n } catch {\n console.warn(\"[ox-content] Native bindings not available, search disabled\");\n return null;\n }\n }\n return oxContent;\n}\n\n/**\n * Splits a raw query into free-text terms and `@scope` prefixes.\n */\nexport function parseScopedSearchQuery(query: string): ScopedSearchQuery {\n return importNapiModuleSync().parseScopedSearchQuery(query);\n}\n\n/**\n * Derives hierarchical search scopes from a document id or URL.\n *\n * For example, `api/math/index` yields `[\"api\", \"api/math\"]`.\n */\nexport function getSearchDocumentScopes(doc: Pick<SearchDocument, \"id\" | \"url\">): string[] {\n return importNapiModuleSync().getSearchDocumentScopes(doc.id ?? \"\", doc.url ?? \"\");\n}\n\n/**\n * Returns true when a search document belongs to at least one requested scope.\n */\nexport function matchesSearchScopes(\n doc: Pick<SearchDocument, \"id\" | \"url\">,\n scopes: string[],\n): boolean {\n return importNapiModuleSync().matchesSearchScopes(doc.id ?? \"\", doc.url ?? \"\", scopes);\n}\n\n/**\n * Resolves search options with defaults.\n */\nexport function resolveSearchOptions(\n options: SearchOptions | boolean | undefined,\n): ResolvedSearchOptions {\n if (options === false) {\n return {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search documentation...\",\n hotkey: \"/\",\n };\n }\n\n const opts = typeof options === \"object\" ? options : {};\n\n return {\n enabled: opts.enabled ?? true,\n limit: opts.limit ?? 10,\n prefix: opts.prefix ?? true,\n placeholder: opts.placeholder ?? \"Search documentation...\",\n hotkey: opts.hotkey ?? \"/\",\n };\n}\n\n/**\n * Builds the search index from Markdown files.\n */\nexport async function buildSearchIndex(\n srcDir: string,\n base: string,\n extensions: readonly string[] = DEFAULT_MARKDOWN_EXTENSIONS,\n): Promise<string> {\n const napi = await getOxContent();\n\n if (!napi) {\n return JSON.stringify({\n documents: [],\n index: {},\n df: {},\n avg_dl: 0,\n doc_count: 0,\n });\n }\n\n return napi.buildSearchIndexFromDirectory(srcDir, base, [...extensions]);\n}\n\n/**\n * Writes the search index to a file.\n */\nexport async function writeSearchIndex(indexJson: string, outDir: string): Promise<void> {\n const napi = await getOxContent();\n\n if (!napi) {\n return;\n }\n\n napi.writeSearchIndex(indexJson, outDir);\n}\n\n/**\n * Client-side search module code.\n * This is injected into the bundle as a virtual module.\n */\nexport function generateSearchModule(options: ResolvedSearchOptions, indexPath: string): string {\n return importNapiModuleSync().generateSearchModuleFromOptions(options, indexPath);\n}\n","/**\n * Dev server middleware for ox-content SSG.\n *\n * Serves fully-rendered HTML pages (with navigation, theme, etc.)\n * during `vite dev`, matching the SSG build output.\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport type { Connect } from \"vite\";\nimport { transformMarkdown } from \"./transform\";\nimport { transformAllPlugins } from \"./plugins\";\nimport { resetTabGroupCounter } from \"./plugins\";\nimport { protectMermaidSvgs, restoreMermaidSvgs } from \"./plugins/mermaid-protect\";\nimport { transformIslands, hasIslands, resetIslandCounter } from \"./island\";\nimport {\n collectMarkdownFiles,\n buildNavItems,\n buildThemeNavItems,\n extractTitle,\n getUrlPath,\n generateHtmlPage,\n formatTitle,\n resolveNavigationGroups,\n} from \"./ssg\";\nimport type { NavGroup, SsgPageData, SsgEntryPageConfig } from \"./ssg\";\nimport type { ResolvedOptions } from \"./types\";\nimport type { HeroConfig, FeatureConfig } from \"./types\";\nimport { normalizeVitePressFrontmatter } from \"./vitepress\";\nimport { isMarkdownFilePath } from \"./markdown\";\n\n/** File extensions to skip in the middleware. */\nconst SKIP_EXTENSIONS = new Set([\n \".js\",\n \".ts\",\n \".css\",\n \".scss\",\n \".less\",\n \".svg\",\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".ico\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".json\",\n \".map\",\n \".mp4\",\n \".webm\",\n \".mp3\",\n \".pdf\",\n]);\n\n/** Vite internal URL prefixes to skip. */\nconst VITE_INTERNAL_PREFIXES = [\"/@vite/\", \"/@fs/\", \"/@id/\", \"/__\"];\n\n/**\n * Check if a request URL should be skipped by the dev server middleware.\n */\nfunction shouldSkip(url: string): boolean {\n // Skip Vite internal URLs\n for (const prefix of VITE_INTERNAL_PREFIXES) {\n if (url.startsWith(prefix)) return true;\n }\n\n // Skip node_modules\n if (url.includes(\"/node_modules/\")) return true;\n\n // Skip requests with known static file extensions\n const extMatch = url.match(/\\.([a-zA-Z0-9]+)(?:\\?|$)/);\n if (extMatch) {\n const ext = \".\" + extMatch[1].toLowerCase();\n if (SKIP_EXTENSIONS.has(ext)) return true;\n }\n\n return false;\n}\n\n/**\n * Resolve a request URL to a markdown file path.\n * Returns null if no matching file exists.\n */\nasync function resolveMarkdownFile(\n url: string,\n srcDir: string,\n extensions: readonly string[],\n): Promise<string | null> {\n // Remove query string and hash\n let pathname = url.split(\"?\")[0].split(\"#\")[0];\n\n // Remove trailing /index.html\n if (pathname.endsWith(\"/index.html\")) {\n pathname = pathname.slice(0, -\"/index.html\".length) || \"/\";\n }\n\n // Remove trailing slash (except for root)\n if (pathname !== \"/\" && pathname.endsWith(\"/\")) {\n pathname = pathname.slice(0, -1);\n }\n\n const routePath = pathname === \"/\" ? \"\" : pathname.slice(1);\n const directCandidates =\n pathname === \"/\"\n ? extensions.map((extension) => `index${extension}`)\n : isMarkdownFilePath(routePath, extensions)\n ? [routePath]\n : extensions.map((extension) => `${routePath}${extension}`);\n\n for (const relativePath of directCandidates) {\n const filePath = path.join(srcDir, relativePath);\n try {\n await fs.access(filePath);\n return filePath;\n } catch {\n // Try the next extension.\n }\n }\n\n for (const extension of extensions) {\n const indexPath = path.join(srcDir, routePath, `index${extension}`);\n try {\n await fs.access(indexPath);\n return indexPath;\n } catch {\n // Try the next extension.\n }\n }\n\n return null;\n}\n\n/**\n * Inject Vite HMR client script into the HTML.\n */\nfunction injectViteHmrClient(html: string): string {\n const hmrScript = `<script type=\"module\" src=\"/@vite/client\"></script>\n<script type=\"module\">\nif (import.meta.hot) {\n const reexecuteBodyScripts = () => {\n const scripts = Array.from(document.body.querySelectorAll('script'));\n for (const script of scripts) {\n const nextScript = document.createElement('script');\n for (const attr of script.attributes) {\n nextScript.setAttribute(attr.name, attr.value);\n }\n nextScript.textContent = script.textContent;\n script.replaceWith(nextScript);\n }\n };\n\n const applyHotUpdate = async () => {\n const nextUrl = new URL(window.location.href);\n nextUrl.searchParams.set('__ox_hmr', String(Date.now()));\n\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n const theme = document.documentElement.getAttribute('data-theme');\n\n const response = await fetch(nextUrl.toString(), {\n cache: 'no-store',\n headers: {\n 'x-ox-content-hmr': '1',\n },\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch updated page');\n }\n\n const nextHtml = await response.text();\n const nextDocument = new DOMParser().parseFromString(nextHtml, 'text/html');\n\n if (!nextDocument.body) {\n throw new Error('Updated page is missing a body');\n }\n\n document.title = nextDocument.title;\n document.body.innerHTML = nextDocument.body.innerHTML;\n reexecuteBodyScripts();\n\n if (theme) {\n document.documentElement.setAttribute('data-theme', theme);\n }\n\n window.scrollTo({ left: scrollX, top: scrollY });\n };\n\n let pendingUpdate = Promise.resolve();\n\n import.meta.hot.on('ox-content:update', () => {\n pendingUpdate = pendingUpdate\n .then(() => applyHotUpdate())\n .catch((error) => {\n console.warn('[ox-content] HMR patch failed, falling back to reload.', error);\n location.reload();\n });\n });\n}\n</script>`;\n\n return html.replace(\"</head>\", hmrScript + \"\\n</head>\");\n}\n\n/**\n * Dev server state for caching.\n */\ninterface DevServerCache {\n /** Cached navigation groups. Invalidated on file add/unlink. */\n navGroups: NavGroup[] | null;\n /** Cached rendered HTML keyed by absolute file path. */\n pages: Map<string, string>;\n /** Cached site name. Computed once. */\n siteName: string | null;\n}\n\n/**\n * Create a dev server cache instance.\n */\nexport function createDevServerCache(): DevServerCache {\n return {\n navGroups: null,\n pages: new Map(),\n siteName: null,\n };\n}\n\n/**\n * Invalidate navigation cache (called on file add/unlink).\n */\nexport function invalidateNavCache(cache: DevServerCache): void {\n cache.navGroups = null;\n // Also clear all page caches since navigation HTML is embedded in pages\n cache.pages.clear();\n}\n\n/**\n * Invalidate page cache for a specific file (called on file change).\n */\nexport function invalidatePageCache(cache: DevServerCache, filePath: string): void {\n cache.pages.delete(filePath);\n}\n\n/**\n * Resolve site name from options or package.json.\n */\nasync function resolveSiteName(options: ResolvedOptions, root: string): Promise<string> {\n if (options.ssg.siteName) {\n return options.ssg.siteName;\n }\n\n try {\n const pkgPath = path.join(root, \"package.json\");\n const pkg = JSON.parse(await fs.readFile(pkgPath, \"utf-8\"));\n if (pkg.name) {\n return formatTitle(pkg.name);\n }\n } catch {\n // Use default\n }\n\n return \"Documentation\";\n}\n\n/**\n * Render a single markdown page to full HTML.\n */\nasync function renderPage(\n filePath: string,\n options: ResolvedOptions,\n navGroups: NavGroup[],\n siteName: string,\n base: string,\n root: string,\n): Promise<string> {\n const srcDir = path.resolve(root, options.srcDir);\n\n // Reset counters for clean render\n resetTabGroupCounter();\n resetIslandCounter();\n\n // Read markdown content\n const content = await fs.readFile(filePath, \"utf-8\");\n\n // Transform markdown to HTML\n const result = await transformMarkdown(content, filePath, options, {\n convertMdLinks: true,\n baseUrl: base,\n sourcePath: filePath,\n });\n const frontmatter = normalizeVitePressFrontmatter(result.frontmatter);\n\n let transformedHtml = result.html;\n\n // Protect mermaid SVGs from rehype processing\n const { html: protectedHtml, svgs: mermaidSvgs } = protectMermaidSvgs(transformedHtml);\n transformedHtml = protectedHtml;\n\n // Transform all plugins\n transformedHtml = await transformAllPlugins(transformedHtml, {\n tabs: true,\n youtube: true,\n github: options.embeds.github,\n openGraph: options.embeds.openGraph,\n pm: options.embeds.pm,\n spotify: options.embeds.spotify,\n stackBlitz: options.embeds.stackBlitz,\n twitter: options.embeds.twitter,\n bluesky: options.embeds.bluesky,\n webContainer: options.embeds.webContainer,\n mermaid: true,\n githubToken: process.env.GITHUB_TOKEN,\n });\n\n // Transform Island components\n if (hasIslands(transformedHtml)) {\n const islandResult = await transformIslands(transformedHtml);\n transformedHtml = islandResult.html;\n }\n\n // Restore protected mermaid SVGs\n transformedHtml = restoreMermaidSvgs(transformedHtml, mermaidSvgs);\n\n // Extract title\n const title = extractTitle(transformedHtml, frontmatter);\n const description = frontmatter.description as string | undefined;\n\n // Check if this is an entry page\n let entryPage: SsgEntryPageConfig | undefined;\n if (frontmatter.layout === \"entry\") {\n entryPage = {\n hero: frontmatter.hero as HeroConfig | undefined,\n features: frontmatter.features as FeatureConfig[] | undefined,\n };\n }\n\n // Build page data\n const pageData: SsgPageData = {\n title,\n description,\n content: transformedHtml,\n toc: result.toc,\n frontmatter,\n path: getUrlPath(filePath, srcDir),\n href: getUrlPath(filePath, srcDir) || \"/\",\n entryPage,\n };\n\n // Generate full HTML page\n let html = await generateHtmlPage(\n pageData,\n navGroups,\n siteName,\n base,\n options.ssg.ogImage,\n options.ssg.theme,\n );\n\n // Inject Vite HMR client for live reload\n html = injectViteHmrClient(html);\n\n return html;\n}\n\n/**\n * Create the dev server middleware for SSG page serving.\n */\nexport function createDevServerMiddleware(\n options: ResolvedOptions,\n root: string,\n cache: DevServerCache,\n): Connect.NextHandleFunction {\n const srcDir = path.resolve(root, options.srcDir);\n const base = options.base.endsWith(\"/\") ? options.base : options.base + \"/\";\n\n return async (req, res, next) => {\n const url = req.url;\n if (!url) return next();\n\n // Strip base from URL for routing\n let routeUrl = url;\n if (base !== \"/\" && routeUrl.startsWith(base)) {\n routeUrl = \"/\" + routeUrl.slice(base.length);\n }\n\n // Skip non-page requests\n if (shouldSkip(routeUrl)) return next();\n\n // Resolve markdown file\n const filePath = await resolveMarkdownFile(routeUrl, srcDir, options.extensions);\n if (!filePath) return next();\n\n try {\n // Check page cache\n const cached = cache.pages.get(filePath);\n if (cached) {\n res.setHeader(\"Content-Type\", \"text/html\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.end(cached);\n return;\n }\n\n // Resolve site name (cached after first call)\n if (!cache.siteName) {\n cache.siteName = await resolveSiteName(options, root);\n }\n\n // Build navigation if not cached\n if (!cache.navGroups) {\n const markdownFiles = await collectMarkdownFiles(srcDir, options.extensions);\n cache.navGroups =\n resolveNavigationGroups(options.ssg.navigation, base, options.ssg.extension) ??\n (options.ssg.theme?.sidebar.length\n ? buildThemeNavItems(options.ssg.theme.sidebar, base, options.ssg.extension)\n : buildNavItems(markdownFiles, srcDir, base, options.ssg.extension));\n }\n\n // Render the page\n const html = await renderPage(filePath, options, cache.navGroups, cache.siteName, base, root);\n\n // Cache the result\n cache.pages.set(filePath, html);\n\n res.setHeader(\"Content-Type\", \"text/html\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.end(html);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`[ox-content:dev] Failed to render ${filePath}:`, message);\n next();\n }\n };\n}\n","/**\n * OG Viewer - Dev tool for previewing Open Graph metadata\n *\n * Accessible at /__og-viewer during development.\n * Shows all pages with their OG metadata, validation warnings,\n * and social card previews.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { glob } from \"glob\";\nimport type { Plugin } from \"vite\";\nimport type { ResolvedOptions } from \"./types\";\nimport { normalizeVitePressFrontmatter } from \"./vitepress\";\nimport { markdownGlobPattern, stripMarkdownExtension } from \"./markdown\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface PageOgData {\n path: string;\n urlPath: string;\n title: string;\n description: string;\n author: string;\n tags: string[];\n ogImageUrl: string;\n warnings: { level: \"error\" | \"warning\"; message: string }[];\n}\n\n// =============================================================================\n// Data Collection\n// =============================================================================\n\nfunction parseFrontmatter(content: string): Record<string, unknown> {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!match) return {};\n\n const yaml = match[1];\n const result: Record<string, unknown> = {};\n\n for (const line of yaml.split(\"\\n\")) {\n const kv = line.match(/^(\\w[\\w-]*):\\s*(.*)$/);\n if (!kv) continue;\n const [, key, rawValue] = kv;\n let value: unknown = rawValue.trim();\n\n // Handle arrays (simple inline: [a, b])\n if (typeof value === \"string\" && value.startsWith(\"[\") && value.endsWith(\"]\")) {\n value = value\n .slice(1, -1)\n .split(\",\")\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, \"\"))\n .filter(Boolean);\n }\n // Strip quotes\n else if (typeof value === \"string\" && /^['\"].*['\"]$/.test(value)) {\n value = value.slice(1, -1);\n }\n // Booleans\n else if (value === \"true\") value = true;\n else if (value === \"false\") value = false;\n\n result[key] = value;\n }\n\n return result;\n}\n\nfunction extractTitle(content: string, frontmatter: Record<string, unknown>): string {\n if (typeof frontmatter.title === \"string\" && frontmatter.title) {\n return frontmatter.title;\n }\n // Fallback: first # heading\n const match = content.match(/^#\\s+(.+)$/m);\n return match ? match[1].trim() : \"\";\n}\n\nfunction getUrlPath(filePath: string, srcDir: string, extensions: readonly string[]): string {\n let rel = path.relative(srcDir, filePath).replace(/\\\\/g, \"/\");\n rel = stripMarkdownExtension(rel, extensions);\n if (rel === \"index\") return \"/\";\n if (rel.endsWith(\"/index\")) rel = rel.slice(0, -\"/index\".length);\n return \"/\" + rel;\n}\n\nfunction computeOgImageUrl(\n urlPath: string,\n base: string,\n siteUrl?: string,\n generateOgImage?: boolean,\n staticOgImage?: string,\n): string {\n if (!generateOgImage) return staticOgImage || \"\";\n\n const cleanBase = base.endsWith(\"/\") ? base : base + \"/\";\n let relativePath: string;\n if (urlPath === \"/\") {\n relativePath = `${cleanBase}og-image.png`;\n } else {\n relativePath = `${cleanBase}${urlPath.replace(/^\\//, \"\")}/og-image.png`;\n }\n\n if (siteUrl) {\n const cleanSiteUrl = siteUrl.replace(/\\/$/, \"\");\n return `${cleanSiteUrl}${relativePath}`;\n }\n return relativePath;\n}\n\nfunction validatePage(\n page: { title: string; description: string; ogImageUrl: string },\n options: ResolvedOptions,\n): { level: \"error\" | \"warning\"; message: string }[] {\n const warnings: { level: \"error\" | \"warning\"; message: string }[] = [];\n\n if (!page.title) {\n warnings.push({ level: \"error\", message: \"title is missing\" });\n } else if (page.title.length > 70) {\n warnings.push({ level: \"warning\", message: `title is too long (${page.title.length}/70)` });\n }\n\n if (!page.description) {\n warnings.push({ level: \"warning\", message: \"description is missing\" });\n } else if (page.description.length > 200) {\n warnings.push({\n level: \"warning\",\n message: `description is too long (${page.description.length}/200)`,\n });\n }\n\n const generateOgImage = options.ogImage || options.ssg.generateOgImage;\n if (generateOgImage && !options.ssg.siteUrl) {\n warnings.push({ level: \"warning\", message: \"ogImage enabled but siteUrl is not set\" });\n }\n\n return warnings;\n}\n\nasync function collectPages(options: ResolvedOptions, root: string): Promise<PageOgData[]> {\n const srcDir = path.resolve(root, options.srcDir);\n const files = await glob(markdownGlobPattern(srcDir, options.extensions), { absolute: true });\n\n const pages: PageOgData[] = [];\n const generateOgImage = options.ogImage || options.ssg.generateOgImage;\n\n for (const file of files.sort()) {\n const content = fs.readFileSync(file, \"utf-8\");\n const frontmatter = normalizeVitePressFrontmatter(parseFrontmatter(content));\n\n // Skip entry layout pages (they are landing pages, not content pages)\n if (frontmatter.layout === \"entry\") continue;\n\n const title = extractTitle(content, frontmatter);\n const description = typeof frontmatter.description === \"string\" ? frontmatter.description : \"\";\n const author = typeof frontmatter.author === \"string\" ? frontmatter.author : \"\";\n const tags = Array.isArray(frontmatter.tags)\n ? (frontmatter.tags as string[])\n : typeof frontmatter.tags === \"string\"\n ? [frontmatter.tags]\n : [];\n\n const urlPath = getUrlPath(file, srcDir, options.extensions);\n const ogImageUrl = computeOgImageUrl(\n urlPath,\n options.base,\n options.ssg.siteUrl,\n generateOgImage,\n options.ssg.ogImage,\n );\n\n const page = {\n path: path.relative(srcDir, file),\n urlPath,\n title,\n description,\n author,\n tags,\n ogImageUrl,\n warnings: [] as PageOgData[\"warnings\"],\n };\n page.warnings = validatePage(page, options);\n pages.push(page);\n }\n\n return pages;\n}\n\n// =============================================================================\n// HTML Rendering\n// =============================================================================\n\nfunction renderViewerHtml(pages: PageOgData[], options: ResolvedOptions): string {\n const generateOgImage = options.ogImage || options.ssg.generateOgImage;\n const totalWarnings = pages.reduce(\n (sum, p) => sum + p.warnings.filter((w) => w.level === \"warning\").length,\n 0,\n );\n const totalErrors = pages.reduce(\n (sum, p) => sum + p.warnings.filter((w) => w.level === \"error\").length,\n 0,\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>OG Viewer - ox-content</title>\n <style>\n :root {\n --bg: #ffffff;\n --bg-card: #f5f7fb;\n --bg-preview: #ffffff;\n --text: #131a30;\n --text-muted: #4f607b;\n --border: #d2dbea;\n --accent: #4f6fae;\n --accent-light: #eef2fa;\n --error: #dc2626;\n --error-bg: #fef2f2;\n --warning: #d97706;\n --warning-bg: #fffbeb;\n --success: #16a34a;\n --tag-bg: #ecf3ff;\n --radius: 16px;\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --bg: #060816;\n --bg-card: #0d1528;\n --bg-preview: #10172d;\n --text: #ebf2ff;\n --text-muted: #8ea0bf;\n --border: #223252;\n --accent: #86a4da;\n --accent-light: #151730;\n --error: #f87171;\n --error-bg: #450a0a;\n --warning: #fbbf24;\n --warning-bg: #451a03;\n --success: #4ade80;\n --tag-bg: #131b33;\n }\n }\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: 'IBM Plex Sans', 'Avenir Next', 'Segoe UI', system-ui, sans-serif; background: radial-gradient(circle at top left, rgba(79,111,174,0.10), transparent 24%), radial-gradient(circle at 85% 14%, rgba(145,237,233,0.08), transparent 22%), var(--bg); color: var(--text); }\n .header { padding: 16px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }\n .header svg { width: 28px; height: 28px; color: var(--accent); }\n .header h1 { font-size: 18px; font-weight: 600; }\n .header h1 span { color: var(--text-muted); font-weight: 400; }\n .header-actions { margin-left: auto; }\n .btn { padding: 6px 14px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-card); color: var(--text); cursor: pointer; font-size: 13px; transition: all 0.15s; }\n .btn:hover { border-color: var(--accent); color: var(--accent); }\n .summary { padding: 12px 24px; display: flex; gap: 20px; border-bottom: 1px solid var(--border); font-size: 13px; color: var(--text-muted); flex-wrap: wrap; align-items: center; }\n .summary-item { display: flex; align-items: center; gap: 4px; }\n .summary-item strong { color: var(--text); }\n .summary-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }\n .dot-error { background: var(--error); }\n .dot-warning { background: var(--warning); }\n .dot-success { background: var(--success); }\n .toolbar { padding: 12px 24px; display: flex; gap: 8px; border-bottom: 1px solid var(--border); flex-wrap: wrap; align-items: center; }\n .filter-btn { padding: 4px 12px; border: 1px solid var(--border); border-radius: 16px; background: transparent; color: var(--text-muted); cursor: pointer; font-size: 12px; transition: all 0.15s; }\n .filter-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }\n .search-input { padding: 6px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--text); font-size: 13px; flex: 1; min-width: 200px; }\n .search-input::placeholder { color: var(--text-muted); }\n .container { padding: 24px; display: flex; flex-direction: column; gap: 20px; max-width: 1200px; margin: 0 auto; }\n .card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-card); overflow: hidden; }\n .card-header { padding: 16px; border-bottom: 1px solid var(--border); }\n .card-path { font-size: 12px; color: var(--text-muted); font-family: monospace; margin-bottom: 4px; }\n .card-title { font-size: 16px; font-weight: 600; }\n .card-desc { font-size: 13px; color: var(--text-muted); margin-top: 4px; }\n .card-meta { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; align-items: center; }\n .tag { padding: 2px 8px; background: var(--tag-bg); border-radius: 4px; font-size: 11px; color: var(--text-muted); }\n .card-warnings { padding: 8px 16px; display: flex; flex-direction: column; gap: 4px; }\n .warning-item { font-size: 12px; padding: 4px 8px; border-radius: 4px; }\n .warning-item.error { background: var(--error-bg); color: var(--error); }\n .warning-item.warning { background: var(--warning-bg); color: var(--warning); }\n .card-previews { padding: 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n @media (max-width: 768px) { .card-previews { grid-template-columns: 1fr; } }\n .preview { border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }\n .preview-label { padding: 6px 10px; font-size: 11px; font-weight: 600; color: var(--text-muted); background: var(--bg); border-bottom: 1px solid var(--border); text-transform: uppercase; letter-spacing: 0.5px; }\n .preview-card { background: var(--bg-preview); }\n .preview-img { width: 100%; aspect-ratio: 1200/630; background: linear-gradient(135deg, var(--accent-light), var(--bg-card)); display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 12px; overflow: hidden; }\n .preview-img img { width: 100%; height: 100%; object-fit: cover; }\n .preview-body { padding: 10px 12px; }\n .preview-url { font-size: 11px; color: var(--text-muted); margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .preview-title { font-size: 14px; font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }\n .preview-desc { font-size: 12px; color: var(--text-muted); margin-top: 2px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }\n .empty { text-align: center; padding: 60px; color: var(--text-muted); }\n .spin { animation: spin 0.6s linear infinite; }\n @keyframes spin { to { transform: rotate(360deg); } }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/></svg>\n <h1>OG Viewer <span>/ ox-content</span></h1>\n <div class=\"header-actions\">\n <button class=\"btn\" id=\"refresh-btn\" onclick=\"refresh()\">Refresh</button>\n </div>\n </div>\n <div class=\"summary\" id=\"summary\">\n <div class=\"summary-item\"><strong id=\"s-pages\">${pages.length}</strong>&nbsp;pages</div>\n <div class=\"summary-item\"><span class=\"summary-dot dot-error\"></span>&nbsp;<strong id=\"s-errors\">${totalErrors}</strong>&nbsp;errors</div>\n <div class=\"summary-item\"><span class=\"summary-dot dot-warning\"></span>&nbsp;<strong id=\"s-warnings\">${totalWarnings}</strong>&nbsp;warnings</div>\n <div class=\"summary-item\"><span class=\"summary-dot ${generateOgImage ? \"dot-success\" : \"dot-warning\"}\"></span>&nbsp;ogImage: <strong>${generateOgImage ? \"enabled\" : \"disabled\"}</strong></div>\n </div>\n <div class=\"toolbar\">\n <button class=\"filter-btn active\" data-filter=\"all\" onclick=\"setFilter('all')\">All</button>\n <button class=\"filter-btn\" data-filter=\"warnings\" onclick=\"setFilter('warnings')\">Warnings</button>\n <button class=\"filter-btn\" data-filter=\"errors\" onclick=\"setFilter('errors')\">Errors</button>\n <input class=\"search-input\" type=\"text\" placeholder=\"Search pages...\" oninput=\"applyFilters()\" id=\"search-input\">\n </div>\n <div class=\"container\" id=\"container\"></div>\n\n <script>\n let pages = ${JSON.stringify(pages)};\n let currentFilter = 'all';\n\n function setFilter(f) {\n currentFilter = f;\n document.querySelectorAll('.filter-btn').forEach(b => b.classList.toggle('active', b.dataset.filter === f));\n applyFilters();\n }\n\n function applyFilters() {\n const q = document.getElementById('search-input').value.toLowerCase();\n const filtered = pages.filter(p => {\n if (currentFilter === 'errors' && !p.warnings.some(w => w.level === 'error')) return false;\n if (currentFilter === 'warnings' && !p.warnings.length) return false;\n if (q && !p.path.toLowerCase().includes(q) && !p.title.toLowerCase().includes(q) && !p.description.toLowerCase().includes(q)) return false;\n return true;\n });\n renderCards(filtered);\n }\n\n function esc(s) {\n const d = document.createElement('div');\n d.textContent = s;\n return d.innerHTML;\n }\n\n function renderCards(list) {\n const c = document.getElementById('container');\n if (!list.length) {\n c.innerHTML = '<div class=\"empty\">No pages match the current filter.</div>';\n return;\n }\n c.innerHTML = list.map(p => {\n const warnings = p.warnings.map(w =>\n '<div class=\"warning-item ' + w.level + '\">' + (w.level === 'error' ? '\\\\u2716' : '\\\\u26A0') + ' ' + esc(w.message) + '</div>'\n ).join('');\n const tags = p.tags.map(t => '<span class=\"tag\">' + esc(t) + '</span>').join('');\n const author = p.author ? '<span class=\"tag\">by ' + esc(p.author) + '</span>' : '';\n const imgHtml = p.ogImageUrl\n ? '<img src=\"' + esc(p.ogImageUrl) + '\" onerror=\"this.parentNode.innerHTML=\\\\'No OG image\\\\'\">'\n : 'No OG image';\n const siteHost = ${JSON.stringify(options.ssg.siteUrl || \"example.com\")};\n return '<div class=\"card\">'\n + '<div class=\"card-header\">'\n + '<div class=\"card-path\">' + esc(p.path) + ' &rarr; ' + esc(p.urlPath) + '</div>'\n + '<div class=\"card-title\">' + (esc(p.title) || '<em style=\"color:var(--error)\">No title</em>') + '</div>'\n + (p.description ? '<div class=\"card-desc\">' + esc(p.description) + '</div>' : '')\n + (tags || author ? '<div class=\"card-meta\">' + author + tags + '</div>' : '')\n + '</div>'\n + (warnings ? '<div class=\"card-warnings\">' + warnings + '</div>' : '')\n + '<div class=\"card-previews\">'\n + '<div class=\"preview\"><div class=\"preview-label\">Twitter (summary_large_image)</div><div class=\"preview-card\"><div class=\"preview-img\">' + imgHtml + '</div><div class=\"preview-body\"><div class=\"preview-url\">' + esc(siteHost) + '</div><div class=\"preview-title\">' + esc(p.title) + '</div><div class=\"preview-desc\">' + esc(p.description) + '</div></div></div></div>'\n + '<div class=\"preview\"><div class=\"preview-label\">Facebook (Open Graph)</div><div class=\"preview-card\"><div class=\"preview-img\">' + imgHtml + '</div><div class=\"preview-body\"><div class=\"preview-url\">' + esc(siteHost) + '</div><div class=\"preview-title\">' + esc(p.title) + '</div><div class=\"preview-desc\">' + esc(p.description) + '</div></div></div></div>'\n + '</div>'\n + '</div>';\n }).join('');\n }\n\n async function refresh() {\n const btn = document.getElementById('refresh-btn');\n btn.textContent = 'Refreshing...';\n btn.disabled = true;\n try {\n const res = await fetch('/__og-viewer/api/pages');\n pages = await res.json();\n updateSummary();\n applyFilters();\n } catch(e) {\n console.error('Refresh failed:', e);\n } finally {\n btn.textContent = 'Refresh';\n btn.disabled = false;\n }\n }\n\n function updateSummary() {\n document.getElementById('s-pages').textContent = pages.length;\n document.getElementById('s-errors').textContent = pages.reduce((s,p) => s + p.warnings.filter(w => w.level === 'error').length, 0);\n document.getElementById('s-warnings').textContent = pages.reduce((s,p) => s + p.warnings.filter(w => w.level === 'warning').length, 0);\n }\n\n renderCards(pages);\n </script>\n</body>\n</html>`;\n}\n\n// =============================================================================\n// Plugin\n// =============================================================================\n\nexport function createOgViewerPlugin(options: ResolvedOptions): Plugin {\n return {\n name: \"ox-content:og-viewer\",\n apply: \"serve\",\n\n configureServer(server) {\n server.middlewares.use(async (req, res, next) => {\n if (req.url === \"/__og-viewer\" || req.url === \"/__og-viewer/\") {\n const root = server.config.root || process.cwd();\n try {\n const pages = await collectPages(options, root);\n const html = renderViewerHtml(pages, options);\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(html);\n } catch (err) {\n res.statusCode = 500;\n res.end(`OG Viewer error: ${err instanceof Error ? err.message : String(err)}`);\n }\n return;\n }\n\n if (req.url === \"/__og-viewer/api/pages\") {\n const root = server.config.root || process.cwd();\n try {\n const pages = await collectPages(options, root);\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.end(JSON.stringify(pages));\n } catch (err) {\n res.statusCode = 500;\n res.end(JSON.stringify({ error: String(err) }));\n }\n return;\n }\n\n next();\n });\n },\n };\n}\n","/**\n * i18n plugin for Ox Content.\n *\n * Provides:\n * - Dictionary loading and validation at build time\n * - Virtual module for i18n config\n * - Build-time i18n checking\n * - Locale-aware routing middleware for dev server\n */\n\nimport * as path from \"path\";\nimport * as fs from \"fs\";\nimport type { Plugin, ViteDevServer } from \"vite\";\nimport { importNapiModule } from \"./napi\";\nimport type { I18nOptions, ResolvedI18nOptions, LocaleConfig, ResolvedOptions } from \"./types\";\n\n/**\n * Resolves i18n options with defaults.\n */\nexport function resolveI18nOptions(\n options: I18nOptions | false | undefined,\n): ResolvedI18nOptions | false {\n if (options === false) return false;\n if (!options || !options.enabled) {\n return false;\n }\n\n const defaultLocale = options.defaultLocale ?? \"en\";\n const locales: LocaleConfig[] = options.locales ?? [{ code: defaultLocale, name: defaultLocale }];\n\n // Ensure default locale is in the locales list\n if (!locales.some((l) => l.code === defaultLocale)) {\n locales.unshift({ code: defaultLocale, name: defaultLocale });\n }\n\n return {\n enabled: true,\n dir: options.dir ?? \"content/i18n\",\n defaultLocale,\n locales,\n hideDefaultLocale: options.hideDefaultLocale ?? true,\n check: options.check ?? true,\n functionNames: options.functionNames ?? [\"t\", \"$t\"],\n };\n}\n\n/**\n * Creates the i18n sub-plugin for the Vite plugin array.\n */\nexport function createI18nPlugin(resolvedOptions: ResolvedOptions): Plugin {\n const i18nOptions = resolvedOptions.i18n;\n let root = process.cwd();\n\n return {\n name: \"ox-content:i18n\",\n\n configResolved(config) {\n root = config.root;\n },\n\n resolveId(id) {\n if (id === \"virtual:ox-content/i18n\") {\n return \"\\0virtual:ox-content/i18n\";\n }\n return null;\n },\n\n load(id) {\n if (id === \"\\0virtual:ox-content/i18n\") {\n if (!i18nOptions) {\n return `export const i18n = { enabled: false }; export default i18n;`;\n }\n\n return generateI18nModule(i18nOptions, root);\n }\n return null;\n },\n\n async buildStart() {\n if (!i18nOptions || !i18nOptions.check) return;\n\n const dictDir = path.resolve(root, i18nOptions.dir);\n if (!fs.existsSync(dictDir)) {\n console.warn(`[ox-content:i18n] Dictionary directory not found: ${dictDir}`);\n return;\n }\n\n try {\n const { checkI18nProject } = await importNapiModule();\n const checkResult = checkI18nProject(\n dictDir,\n [path.resolve(root, \"src\"), path.resolve(root, \"content\")],\n i18nOptions.functionNames,\n i18nOptions.defaultLocale,\n );\n if (checkResult.errorCount > 0 || checkResult.warningCount > 0) {\n for (const diag of checkResult.diagnostics) {\n if (diag.severity === \"error\") {\n console.error(`[ox-content:i18n] ${diag.message}`);\n } else if (diag.severity === \"warning\") {\n console.warn(`[ox-content:i18n] ${diag.message}`);\n }\n }\n }\n } catch {\n // NAPI binding not available; skip checks\n }\n },\n\n configureServer(server: ViteDevServer) {\n if (!i18nOptions) return;\n\n // Watch dictionary directory for changes\n const dictDir = path.resolve(root, i18nOptions.dir);\n if (fs.existsSync(dictDir)) {\n server.watcher.add(dictDir);\n\n server.watcher.on(\"change\", (filePath: string) => {\n if (!filePath.startsWith(dictDir)) return;\n if (!/\\.(json|yaml|yml)$/.test(filePath)) return;\n\n // Invalidate the virtual module\n const mod = server.moduleGraph.getModuleById(\"\\0virtual:ox-content/i18n\");\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n }\n\n // Trigger full reload\n server.ws.send({ type: \"full-reload\" });\n });\n }\n\n // Add locale routing middleware\n server.middlewares.use((req, _res, next) => {\n if (!req.url) return next();\n\n // Parse locale from URL\n const url = req.url;\n const localeMatch = url.match(/^\\/([A-Za-z]{2,3}(?:-[A-Za-z0-9]+)*)(\\/|$)/);\n\n if (localeMatch) {\n const localeCode = localeMatch[1];\n const isKnown = i18nOptions.locales.some((l) => l.code === localeCode);\n if (isKnown) {\n // Set locale header for downstream middleware\n (req as any).__oxLocale = localeCode;\n }\n } else if (i18nOptions.hideDefaultLocale) {\n // No locale prefix: use default locale\n (req as any).__oxLocale = i18nOptions.defaultLocale;\n }\n\n next();\n });\n },\n };\n}\n\n/**\n * Generates the virtual module for i18n configuration.\n */\nexport function generateI18nModule(options: ResolvedI18nOptions, root: string): string {\n const dictDir = path.resolve(root, options.dir);\n const config = {\n defaultLocale: options.defaultLocale,\n locales: options.locales,\n hideDefaultLocale: options.hideDefaultLocale,\n };\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const napi = require(\"@ox-content/napi\") as {\n generateI18nModule?: (dictDir: string, runtimeConfig: typeof config) => string;\n };\n\n if (typeof napi.generateI18nModule === \"function\") {\n return napi.generateI18nModule(dictDir, config);\n }\n } catch (error) {\n throw new Error(\n `[ox-content:i18n] Failed to load @ox-content/napi for i18n module generation: ${String(error)}`,\n );\n }\n\n throw new Error(\n \"[ox-content:i18n] @ox-content/napi does not expose generateI18nModule. Please rebuild the NAPI package.\",\n );\n}\n","import { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { glob } from \"glob\";\nimport { extractDocsTests, type DocsTestOptions, type ExtractedCodeBlock } from \"./code-blocks\";\nimport { extractDocs, resolveDocsOptions } from \"./docs\";\nimport type { DocEntry, DocsOptions, ExtractedDocs, ResolvedDocsOptions } from \"./types\";\n\nexport interface CollectedDocsTest extends ExtractedCodeBlock {\n sourcePath: string;\n relativePath: string;\n index: number;\n}\n\nexport type DocsTestSource = \"markdown\" | \"jsdoc\";\n\nexport interface DocsTestHarnessOptions extends DocsTestOptions {\n /**\n * Source kind to scan for runnable examples.\n * - `markdown` scans Markdown files for fenced code blocks.\n * - `jsdoc` scans JSDoc/TSDoc `@example` blocks through ox-content's docs extractor.\n * @default \"markdown\"\n */\n source?: DocsTestSource;\n\n /**\n * Markdown glob patterns, or source-file include globs when `source` is `jsdoc`.\n */\n include?: string | string[];\n\n /**\n * Glob patterns to skip. For `jsdoc`, this is passed to docs extraction as `exclude`.\n */\n ignore?: string | string[];\n\n /**\n * Working directory used for globs and generated test files.\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Source directories to scan when `source` is `jsdoc`.\n * @default [\"./src\"]\n */\n src?: string | string[];\n\n /**\n * Additional docs extraction options for `jsdoc` source mode.\n */\n docs?: DocsOptions;\n}\n\nexport interface DocsTestFileOptions extends DocsTestHarnessOptions {\n /**\n * Directory for generated Vitest files.\n * @default \".cache/ox-content-docs-tests\"\n */\n generatedDir?: string;\n\n /**\n * Remove the generated directory before writing files.\n * @default true\n */\n clean?: boolean;\n\n /**\n * Optional code prepended to every generated test file.\n */\n setupCode?: string;\n\n /**\n * How each generated file should execute the docs block.\n * - `test` wraps the block in a generated Vitest test, similar to Cargo doctests.\n * - `module` writes the block as-is for snippets that declare their own tests.\n * @default \"test\"\n */\n executionMode?: \"test\" | \"module\";\n\n /**\n * Module used for the generated `test` import.\n * @default \"vitest\"\n */\n testImport?: string;\n\n /**\n * Optional static import specifier rewrites for generated test files.\n */\n importRewrites?: Record<string, string>;\n}\n\nexport interface WrittenDocsTestFile {\n filePath: string;\n sourcePath: string;\n relativePath: string;\n startLine: number;\n endLine: number;\n language: string;\n}\n\nexport interface DocsTestWriteResult {\n cwd: string;\n generatedDir: string;\n blocks: CollectedDocsTest[];\n files: WrittenDocsTestFile[];\n}\n\nexport interface RunDocsTestsOptions extends DocsTestFileOptions {\n /**\n * Vitest-compatible command to run.\n * @default \"vitest\"\n */\n vitestCommand?: string;\n\n /**\n * Arguments passed before generated test file paths.\n * @default [\"run\"]\n */\n vitestArgs?: string[];\n\n /**\n * Environment overrides for the Vitest child process.\n */\n env?: NodeJS.ProcessEnv;\n\n /**\n * Allow a scan that finds no runnable docs tests.\n * @default false\n */\n allowEmpty?: boolean;\n}\n\nexport interface DocsTestRunResult extends DocsTestWriteResult {\n command: string;\n args: string[];\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport class DocsTestRunError extends Error {\n readonly result: DocsTestRunResult;\n\n constructor(result: DocsTestRunResult) {\n const command = [result.command, ...result.args].join(\" \");\n super(`[ox-content] Docs tests failed with exit code ${result.exitCode}: ${command}`);\n this.name = \"DocsTestRunError\";\n this.result = result;\n }\n}\n\nexport async function collectDocsTests(\n options: DocsTestHarnessOptions,\n): Promise<CollectedDocsTest[]> {\n const cwd = path.resolve(options.cwd ?? process.cwd());\n if ((options.source ?? \"markdown\") === \"jsdoc\") {\n return collectJsdocDocsTests(options, cwd);\n }\n\n return collectMarkdownDocsTests(options, cwd);\n}\n\nasync function collectMarkdownDocsTests(\n options: DocsTestHarnessOptions,\n cwd: string,\n): Promise<CollectedDocsTest[]> {\n const include = toArray(options.include);\n const ignore = toArray(options.ignore);\n const files = new Map<string, string>();\n\n if (include.length === 0) {\n throw new Error(\"[ox-content] Docs test include patterns are required for markdown sources.\");\n }\n\n for (const pattern of include) {\n const matches = await glob(pattern, {\n absolute: true,\n cwd,\n ignore,\n nodir: true,\n });\n\n for (const filePath of matches) {\n const absolutePath = path.resolve(filePath);\n files.set(absolutePath, normalizePath(path.relative(cwd, absolutePath)));\n }\n }\n\n const blocks: CollectedDocsTest[] = [];\n let index = 0;\n for (const [sourcePath, relativePath] of [...files.entries()].sort((left, right) =>\n left[0].localeCompare(right[0]),\n )) {\n const source = await fs.readFile(sourcePath, \"utf-8\");\n const extracted = await extractDocsTests(source, {\n languages: options.languages,\n requireMeta: options.requireMeta,\n });\n\n for (const block of extracted) {\n blocks.push({\n ...block,\n sourcePath,\n relativePath,\n index,\n });\n index += 1;\n }\n }\n\n return blocks;\n}\n\nasync function collectJsdocDocsTests(\n options: DocsTestHarnessOptions,\n cwd: string,\n): Promise<CollectedDocsTest[]> {\n const docsOptions = resolveJsdocDocsOptions(options, cwd);\n const docs = await extractDocs(docsOptions.src, docsOptions);\n const blocks: CollectedDocsTest[] = [];\n let index = 0;\n\n for (const doc of sortDocs(docs)) {\n for (const entry of sortEntries(doc.entries)) {\n for (const example of entry.examples ?? []) {\n const extracted = await extractDocsTests(example, {\n languages: options.languages,\n requireMeta: options.requireMeta,\n });\n const sourcePath = resolveEntrySourcePath(entry, doc, cwd);\n const relativePath = relativeSourcePath(cwd, sourcePath);\n\n for (const block of extracted) {\n blocks.push({\n ...block,\n sourcePath,\n relativePath,\n startLine: entry.line,\n endLine: entry.endLine,\n index,\n });\n index += 1;\n }\n }\n }\n }\n\n return blocks;\n}\n\nfunction resolveJsdocDocsOptions(\n options: DocsTestHarnessOptions,\n cwd: string,\n): ResolvedDocsOptions {\n const docsOptions: DocsOptions = {\n ...options.docs,\n };\n\n if (options.src !== undefined) {\n docsOptions.src = toArray(options.src);\n }\n if (options.include !== undefined) {\n docsOptions.include = toArray(options.include);\n }\n if (options.ignore !== undefined) {\n docsOptions.exclude = toArray(options.ignore);\n }\n\n const resolved = resolveDocsOptions(docsOptions);\n return {\n ...resolved,\n src: resolved.src.map((sourceDir) => path.resolve(cwd, sourceDir)),\n entryPoints: resolved.entryPoints?.map((entryPoint) => ({\n ...entryPoint,\n path: path.resolve(cwd, entryPoint.path),\n })),\n };\n}\n\nfunction sortDocs(docs: ExtractedDocs[]): ExtractedDocs[] {\n return [...docs].sort((left, right) => left.file.localeCompare(right.file));\n}\n\nfunction sortEntries(entries: DocEntry[]): DocEntry[] {\n return [...entries].sort((left, right) => {\n const byFile = left.file.localeCompare(right.file);\n if (byFile !== 0) return byFile;\n const byLine = left.line - right.line;\n if (byLine !== 0) return byLine;\n return left.name.localeCompare(right.name);\n });\n}\n\nfunction resolveEntrySourcePath(entry: DocEntry, doc: ExtractedDocs, cwd: string): string {\n const sourcePath = entry.file || doc.file;\n return path.isAbsolute(sourcePath) ? path.resolve(sourcePath) : path.resolve(cwd, sourcePath);\n}\n\nfunction relativeSourcePath(cwd: string, sourcePath: string): string {\n const relativePath = path.relative(cwd, sourcePath);\n if (!relativePath.startsWith(\"..\") && !path.isAbsolute(relativePath)) {\n return normalizePath(relativePath);\n }\n return normalizePath(sourcePath);\n}\n\nexport async function writeDocsTestFiles(\n options: DocsTestFileOptions,\n): Promise<DocsTestWriteResult> {\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const generatedDir = path.resolve(cwd, options.generatedDir ?? \".cache/ox-content-docs-tests\");\n const clean = options.clean ?? true;\n const blocks = await collectDocsTests({ ...options, cwd });\n\n if (clean) {\n await fs.rm(generatedDir, { recursive: true, force: true });\n }\n await fs.mkdir(generatedDir, { recursive: true });\n\n const files = await Promise.all(\n blocks.map(async (block) => {\n const filePath = path.join(generatedDir, docsTestFileName(block));\n await fs.writeFile(filePath, renderDocsTestFile(block, options), \"utf-8\");\n return {\n filePath,\n sourcePath: block.sourcePath,\n relativePath: block.relativePath,\n startLine: block.startLine,\n endLine: block.endLine,\n language: block.language,\n };\n }),\n );\n\n return {\n cwd,\n generatedDir,\n blocks,\n files,\n };\n}\n\nexport async function runDocsTests(options: RunDocsTestsOptions): Promise<DocsTestRunResult> {\n const writeResult = await writeDocsTestFiles(options);\n const command = options.vitestCommand ?? \"vitest\";\n const leadingArgs = options.vitestArgs ?? [\"run\"];\n const fileArgs = writeResult.files.map((file) => file.filePath);\n const args = [...leadingArgs, ...fileArgs];\n\n if (fileArgs.length === 0) {\n if (options.allowEmpty) {\n return {\n ...writeResult,\n command,\n args,\n exitCode: 0,\n stdout: \"\",\n stderr: \"\",\n };\n }\n throw new Error(\"[ox-content] No runnable docs test blocks were found.\");\n }\n\n const result = await runCommand(command, args, {\n cwd: writeResult.cwd,\n env: mergeEnv(options.env),\n });\n const runResult = {\n ...writeResult,\n command,\n args,\n ...result,\n };\n\n if (runResult.exitCode !== 0) {\n throw new DocsTestRunError(runResult);\n }\n\n return runResult;\n}\n\nfunction renderDocsTestFile(block: CollectedDocsTest, options: DocsTestFileOptions): string {\n const parts = [\n \"// Generated by @ox-content/vite-plugin docs test harness.\",\n `// Source: ${block.relativePath}:${block.startLine}-${block.endLine}`,\n \"\",\n ];\n const setupCode = options.setupCode?.trimEnd();\n const code = rewriteImports(block.code.trimEnd(), options.importRewrites);\n if (setupCode) {\n parts.push(setupCode, \"\");\n }\n if ((options.executionMode ?? \"test\") === \"module\") {\n parts.push(code, \"\");\n return parts.join(\"\\n\");\n }\n\n const { imports, body } = partitionImports(code);\n parts.push(\n `import { test } from ${JSON.stringify(\n rewriteSpecifier(options.testImport ?? \"vitest\", options.importRewrites),\n )};`,\n );\n if (imports.length > 0) {\n parts.push(...imports);\n }\n parts.push(\n \"\",\n `test(${JSON.stringify(`${block.relativePath}:${block.startLine}`)}, async () => {`,\n );\n if (body.trim().length > 0) {\n parts.push(indentCode(body.trimEnd()));\n }\n parts.push(\"});\", \"\");\n return parts.join(\"\\n\");\n}\n\nfunction partitionImports(source: string): { imports: string[]; body: string } {\n const imports: string[] = [];\n const body: string[] = [];\n const lines = source.split(/\\r?\\n/);\n let currentImport: string[] | undefined;\n\n for (const line of lines) {\n if (currentImport) {\n currentImport.push(line);\n if (endsImportDeclaration(line)) {\n imports.push(currentImport.join(\"\\n\"));\n currentImport = undefined;\n }\n continue;\n }\n\n if (startsStaticImport(line)) {\n if (endsImportDeclaration(line)) {\n imports.push(line);\n } else {\n currentImport = [line];\n }\n continue;\n }\n\n body.push(line);\n }\n\n if (currentImport) {\n body.push(...currentImport);\n }\n\n return { imports, body: body.join(\"\\n\") };\n}\n\nfunction startsStaticImport(line: string): boolean {\n const trimmed = line.trimStart();\n return trimmed.startsWith(\"import \") && !trimmed.startsWith(\"import(\");\n}\n\nfunction endsImportDeclaration(line: string): boolean {\n const trimmed = line.trim();\n return (\n trimmed.endsWith(\";\") ||\n /^import\\s+[\"'][^\"']+[\"']$/.test(trimmed) ||\n /\\sfrom\\s+[\"'][^\"']+[\"']$/.test(trimmed)\n );\n}\n\nfunction indentCode(source: string): string {\n return source\n .split(\"\\n\")\n .map((line) => (line.length > 0 ? ` ${line}` : line))\n .join(\"\\n\");\n}\n\nfunction rewriteImports(source: string, rewrites: Record<string, string> | undefined): string {\n if (!rewrites) {\n return source;\n }\n\n let result = source;\n for (const [from, to] of Object.entries(rewrites)) {\n const escaped = escapeRegExp(from);\n result = result\n .replace(new RegExp(`(from\\\\s+[\"'])${escaped}([\"'])`, \"g\"), `$1${to}$2`)\n .replace(new RegExp(`(import\\\\s+[\"'])${escaped}([\"'])`, \"g\"), `$1${to}$2`)\n .replace(new RegExp(`(import\\\\(\\\\s*[\"'])${escaped}([\"']\\\\s*\\\\))`, \"g\"), `$1${to}$2`);\n }\n return result;\n}\n\n/**\n * Applies the same import rewrite table to harness-owned imports.\n *\n * @internal\n * @example\n * ```ts docs-test\n * import { expect } from \"vitest\";\n * import { extractDocsTests } from \"../../src/code-blocks\";\n *\n * const markdown = [\n * \"```ts docs-test\",\n * \"expect(1 + 1).toBe(2);\",\n * \"```\",\n * ].join(\"\\n\");\n *\n * const blocks = await extractDocsTests(markdown);\n *\n * expect(blocks).toHaveLength(1);\n * expect(blocks[0]?.code).toContain(\"1 + 1\");\n * ```\n */\nfunction rewriteSpecifier(specifier: string, rewrites: Record<string, string> | undefined): string {\n return rewrites?.[specifier] ?? specifier;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction docsTestFileName(block: CollectedDocsTest): string {\n const baseName =\n block.relativePath\n .replace(/^\\.\\//, \"\")\n .replace(/[^A-Za-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"docs-test\";\n return `${baseName}-L${block.startLine}-${block.index + 1}.test.${extensionForLanguage(\n block.language,\n )}`;\n}\n\nfunction extensionForLanguage(language: string): string {\n switch (language.toLowerCase()) {\n case \"jsx\":\n return \"jsx\";\n case \"tsx\":\n return \"tsx\";\n case \"mjs\":\n return \"mjs\";\n case \"mts\":\n return \"mts\";\n case \"js\":\n return \"js\";\n default:\n return \"ts\";\n }\n}\n\nfunction toArray(value: string | string[] | undefined): string[] {\n if (!value) return [];\n return Array.isArray(value) ? value : [value];\n}\n\nfunction normalizePath(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n\nfunction mergeEnv(overrides: NodeJS.ProcessEnv | undefined): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = { ...process.env };\n for (const [key, value] of Object.entries(overrides ?? {})) {\n if (value === undefined) {\n delete env[key];\n } else {\n env[key] = value;\n }\n }\n return env;\n}\n\nfunction runCommand(\n command: string,\n args: string[],\n options: { cwd: string; env: NodeJS.ProcessEnv },\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n\n if (child.stdout) {\n child.stdout.setEncoding(\"utf-8\");\n child.stdout.on(\"data\", (chunk) => {\n stdout += chunk;\n });\n }\n if (child.stderr) {\n child.stderr.setEncoding(\"utf-8\");\n child.stderr.on(\"data\", (chunk) => {\n stderr += chunk;\n });\n }\n child.on(\"error\", reject);\n child.on(\"close\", (exitCode) => {\n resolve({ exitCode: exitCode ?? 1, stdout, stderr });\n });\n });\n}\n","import { createRequire } from \"node:module\";\nimport type { CSpellUserSettings, SpellCheckFileOptions, ValidationIssue } from \"cspell-lib\";\n\nconst require = createRequire(import.meta.url);\n\nconst SUPPORTED_MARKDOWN_LINT_LANGUAGES = [\"en\", \"ja\", \"zh\", \"fr\", \"de\", \"pl\"] as const;\nconst DEFAULT_LANGUAGES = [\"en\"] as const;\nconst DEFAULT_RULES = {\n duplicateHeadings: true,\n headingIncrement: true,\n maxConsecutiveBlankLines: 1,\n repeatedPunctuation: true,\n repeatedWords: true,\n spellcheck: true,\n trailingSpaces: true,\n} as const;\nconst DEFAULT_CSPELL_IMPORTS: Partial<Record<MarkdownLintLanguage, string>> = {\n de: \"@cspell/dict-de-de/cspell-ext.json\",\n en: \"@cspell/dict-en_us/cspell-ext.json\",\n fr: \"@cspell/dict-fr-fr/cspell-ext.json\",\n pl: \"@cspell/dict-pl_pl/cspell-ext.json\",\n};\n\nexport type MarkdownLintLanguage = (typeof SUPPORTED_MARKDOWN_LINT_LANGUAGES)[number];\nexport type MarkdownLintSeverity = \"error\" | \"warning\" | \"info\";\n\n/**\n * Opt-in standard dictionary sources.\n *\n * The default provider uses CSpell dictionary packages because those packages\n * are actively maintained and expose locale-specific dictionaries in a stable\n * config format. Languages without a bundled preset can still be added through\n * custom `imports`.\n */\nexport interface MarkdownLintStandardDictionaryOptions {\n /**\n * Standard dictionary provider.\n * @default \"cspell\"\n */\n provider?: \"cspell\";\n\n /**\n * Languages whose default standard dictionaries should be enabled.\n *\n * Built-in preset package mappings currently exist for `en`, `fr`, `de`,\n * and `pl`. For other languages, use `imports`.\n *\n * @default []\n */\n languages?: MarkdownLintLanguage[];\n\n /**\n * Additional CSpell-compatible imports.\n *\n * This can point at installed packages like\n * `@cspell/dict-fr-fr/cspell-ext.json` or local CSpell config files.\n */\n imports?: string[];\n\n /**\n * Base URL or path used when resolving `imports`.\n *\n * @default new URL(\".\", import.meta.url)\n */\n resolveImportsRelativeTo?: string | URL;\n}\n\n/**\n * Additional dictionary configuration for the Markdown linter.\n */\nexport interface MarkdownLintDictionaryOptions {\n /**\n * Words ignored across all configured languages.\n */\n words?: string[];\n\n /**\n * Extra words to allow per language.\n */\n byLanguage?: Partial<Record<MarkdownLintLanguage, string[]>>;\n\n /**\n * Words that should never produce diagnostics.\n */\n ignoredWords?: string[];\n\n /**\n * Opt-in standard dictionary datasets.\n *\n * By default the linter stays on a minimal built-in dictionary. Enable this\n * to load larger locale dictionaries from a standard external source.\n */\n standard?: MarkdownLintStandardDictionaryOptions | false;\n}\n\n/**\n * Rule switches for Markdown linting.\n */\nexport interface MarkdownLintRuleOptions {\n /**\n * Report headings that repeat the same visible text.\n * @default true\n */\n duplicateHeadings?: boolean;\n\n /**\n * Report heading depth jumps such as `#` -> `###`.\n * @default true\n */\n headingIncrement?: boolean;\n\n /**\n * Maximum number of blank lines allowed in a row.\n * @default 1\n */\n maxConsecutiveBlankLines?: number;\n\n /**\n * Report duplicated terminal punctuation such as `!!` or `??`.\n * @default true\n */\n repeatedPunctuation?: boolean;\n\n /**\n * Report adjacent repeated words in visible prose.\n * @default true\n */\n repeatedWords?: boolean;\n\n /**\n * Enable built-in multilingual spellchecking.\n * @default true\n */\n spellcheck?: boolean;\n\n /**\n * Report trailing spaces.\n * @default true\n */\n trailingSpaces?: boolean;\n}\n\n/**\n * Options for linting Markdown documents.\n */\nexport interface MarkdownLintOptions {\n /**\n * Languages enabled for spellchecking.\n *\n * When `dictionary.standard.languages` is provided and this option is\n * omitted, those languages are used instead.\n *\n * @default ['en']\n */\n languages?: MarkdownLintLanguage[];\n\n /**\n * Rule configuration.\n */\n rules?: MarkdownLintRuleOptions;\n\n /**\n * Built-in and opt-in standard dictionary overrides.\n */\n dictionary?: MarkdownLintDictionaryOptions;\n}\n\n/**\n * A single Markdown lint diagnostic.\n */\nexport interface MarkdownLintDiagnostic {\n /**\n * Stable rule identifier.\n */\n ruleId: string;\n\n /**\n * Diagnostic severity.\n */\n severity: MarkdownLintSeverity;\n\n /**\n * Human-readable explanation.\n */\n message: string;\n\n /**\n * 1-indexed line number.\n */\n line: number;\n\n /**\n * 1-indexed start column.\n */\n column: number;\n\n /**\n * 1-indexed end line.\n */\n endLine: number;\n\n /**\n * 1-indexed end column.\n */\n endColumn: number;\n\n /**\n * Language used for spellchecking, when relevant.\n */\n language?: MarkdownLintLanguage;\n\n /**\n * Suggested replacements, when available.\n */\n suggestions?: string[];\n}\n\n/**\n * Markdown lint report.\n */\nexport interface MarkdownLintResult {\n /**\n * All collected diagnostics.\n */\n diagnostics: MarkdownLintDiagnostic[];\n\n /**\n * Number of error diagnostics.\n */\n errorCount: number;\n\n /**\n * Number of warning diagnostics.\n */\n warningCount: number;\n\n /**\n * Number of info diagnostics.\n */\n infoCount: number;\n}\n\ninterface NormalizedStandardDictionaryOptions {\n imports: string[];\n languages: MarkdownLintLanguage[];\n provider: \"cspell\";\n resolveImportsRelativeTo: string | URL;\n}\n\ninterface InternalNormalizedMarkdownLintOptions {\n dictionary: Omit<MarkdownLintDictionaryOptions, \"standard\"> & {\n standard: NormalizedStandardDictionaryOptions | false;\n };\n languages: MarkdownLintLanguage[];\n rules: Required<MarkdownLintRuleOptions>;\n}\n\ninterface NapiMarkdownLintLanguageWords {\n language: MarkdownLintLanguage;\n words: string[];\n}\n\ninterface NapiMarkdownLintOptions {\n dictionary?: {\n byLanguage?: NapiMarkdownLintLanguageWords[];\n ignoredWords?: string[];\n words?: string[];\n };\n languages?: MarkdownLintLanguage[];\n rules?: Required<MarkdownLintRuleOptions>;\n}\n\ninterface NapiMarkdownLintResult extends MarkdownLintResult {\n maskedDocument: string;\n}\n\ninterface NapiMarkdownLintModule {\n lintMarkdownDocuments?: (\n sources: string[],\n options?: NapiMarkdownLintOptions,\n ) => NapiMarkdownLintResult[];\n lintMarkdown: (source: string, options?: NapiMarkdownLintOptions) => NapiMarkdownLintResult;\n}\n\nlet napiBinding: NapiMarkdownLintModule | null | undefined;\nlet cspellLibPromise: Promise<typeof import(\"cspell-lib\")> | undefined;\n\n/**\n * Lints Markdown prose with the Rust-backed built-in rule engine.\n */\nexport function lintMarkdown(\n source: string,\n options: MarkdownLintOptions = {},\n): MarkdownLintResult {\n const normalizedOptions = normalizeLintOptions(options);\n return lintMarkdownWithNormalizedOptions(source, normalizedOptions);\n}\n\n/**\n * Async Markdown linter that supports opt-in standard dictionaries.\n */\nexport async function lintMarkdownAsync(\n source: string,\n options: MarkdownLintOptions = {},\n): Promise<MarkdownLintResult> {\n const normalizedOptions = normalizeLintOptions(options);\n const [result] = await lintMarkdownDocumentsWithNormalizedOptions([source], normalizedOptions);\n return result ?? createEmptyLintResult();\n}\n\n/**\n * Internal batched Markdown linting entry point used by file-based workflows.\n */\nexport async function lintMarkdownDocumentsAsync(\n sources: string[],\n options: MarkdownLintOptions = {},\n): Promise<MarkdownLintResult[]> {\n const normalizedOptions = normalizeLintOptions(options);\n return lintMarkdownDocumentsWithNormalizedOptions(sources, normalizedOptions);\n}\n\nfunction lintMarkdownWithNormalizedOptions(\n source: string,\n normalizedOptions: InternalNormalizedMarkdownLintOptions,\n): MarkdownLintResult {\n if (normalizedOptions.dictionary.standard) {\n throw new Error(\n \"[ox-content] lintMarkdownAsync is required when dictionary.standard is enabled.\",\n );\n }\n\n const napi = loadNapiBindingSync();\n return stripMaskedDocument(\n napi.lintMarkdown(source, toNapiMarkdownLintOptions(normalizedOptions)),\n );\n}\n\nasync function lintMarkdownDocumentsWithNormalizedOptions(\n sources: string[],\n normalizedOptions: InternalNormalizedMarkdownLintOptions,\n): Promise<MarkdownLintResult[]> {\n if (sources.length === 0) {\n return [];\n }\n\n const napi = loadNapiBindingSync();\n const napiOptions = toNapiMarkdownLintOptions(\n normalizedOptions,\n Boolean(normalizedOptions.dictionary.standard),\n );\n const builtInResults =\n typeof napi.lintMarkdownDocuments === \"function\"\n ? napi.lintMarkdownDocuments(sources, napiOptions)\n : sources.map((source) => napi.lintMarkdown(source, napiOptions));\n\n if (!normalizedOptions.rules.spellcheck || !normalizedOptions.dictionary.standard) {\n return builtInResults.map(stripMaskedDocument);\n }\n\n const standardDiagnostics = await runStandardSpellcheckDocuments(\n builtInResults.map((result) => result.maskedDocument),\n normalizedOptions,\n );\n\n return builtInResults.map((result, index) =>\n summarizeDiagnostics(\n sortDiagnostics(result.diagnostics.concat(standardDiagnostics[index] ?? [])),\n ),\n );\n}\n\nfunction loadNapiBindingSync(): NapiMarkdownLintModule {\n if (napiBinding) {\n return napiBinding;\n }\n\n if (napiBinding === null) {\n throw new Error(\n \"[ox-content] @ox-content/napi is required for Markdown linting. Please ensure the NAPI module is built.\",\n );\n }\n\n try {\n const loaded = require(\"@ox-content/napi\") as NapiMarkdownLintModule & {\n default?: Partial<NapiMarkdownLintModule>;\n };\n napiBinding =\n loaded.default && typeof loaded.default === \"object\"\n ? { ...loaded.default, ...loaded }\n : loaded;\n\n return napiBinding;\n } catch {\n napiBinding = null;\n throw new Error(\n \"[ox-content] @ox-content/napi is required for Markdown linting. Please ensure the NAPI module is built.\",\n );\n }\n}\n\nfunction toNapiMarkdownLintOptions(\n options: InternalNormalizedMarkdownLintOptions,\n disableBuiltinSpellcheck = false,\n): NapiMarkdownLintOptions {\n const byLanguage = Object.entries(options.dictionary.byLanguage ?? {}).map(\n ([language, words]): NapiMarkdownLintLanguageWords => ({\n language: language as MarkdownLintLanguage,\n words,\n }),\n );\n\n return {\n dictionary: {\n byLanguage,\n ignoredWords: options.dictionary.ignoredWords,\n words: options.dictionary.words,\n },\n languages: options.languages,\n rules: {\n ...options.rules,\n spellcheck: disableBuiltinSpellcheck ? false : options.rules.spellcheck,\n },\n };\n}\n\nfunction stripMaskedDocument(result: NapiMarkdownLintResult): MarkdownLintResult {\n return {\n diagnostics: result.diagnostics,\n errorCount: result.errorCount,\n infoCount: result.infoCount,\n warningCount: result.warningCount,\n };\n}\n\nfunction normalizeLintOptions(options: MarkdownLintOptions): InternalNormalizedMarkdownLintOptions {\n const standardDictionary =\n options.dictionary?.standard && typeof options.dictionary.standard === \"object\"\n ? options.dictionary.standard\n : undefined;\n const optionLanguages = options.languages?.filter((language): language is MarkdownLintLanguage =>\n SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language),\n );\n const standardLanguages = standardDictionary?.languages?.filter(\n (language): language is MarkdownLintLanguage =>\n SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language),\n );\n const languages: MarkdownLintLanguage[] = optionLanguages ??\n standardLanguages ?? [...DEFAULT_LANGUAGES];\n\n const standard = normalizeStandardDictionaryOptions(options.dictionary?.standard, languages);\n\n return {\n dictionary: {\n ...options.dictionary,\n standard,\n },\n languages: [...new Set(languages)],\n rules: {\n duplicateHeadings: options.rules?.duplicateHeadings ?? DEFAULT_RULES.duplicateHeadings,\n headingIncrement: options.rules?.headingIncrement ?? DEFAULT_RULES.headingIncrement,\n maxConsecutiveBlankLines:\n options.rules?.maxConsecutiveBlankLines ?? DEFAULT_RULES.maxConsecutiveBlankLines,\n repeatedPunctuation: options.rules?.repeatedPunctuation ?? DEFAULT_RULES.repeatedPunctuation,\n repeatedWords: options.rules?.repeatedWords ?? DEFAULT_RULES.repeatedWords,\n spellcheck: options.rules?.spellcheck ?? DEFAULT_RULES.spellcheck,\n trailingSpaces: options.rules?.trailingSpaces ?? DEFAULT_RULES.trailingSpaces,\n },\n };\n}\n\nfunction normalizeStandardDictionaryOptions(\n standard: MarkdownLintDictionaryOptions[\"standard\"],\n fallbackLanguages: MarkdownLintLanguage[],\n): NormalizedStandardDictionaryOptions | false {\n if (!standard) {\n return false;\n }\n\n const languages =\n standard.languages?.filter((language): language is MarkdownLintLanguage =>\n SUPPORTED_MARKDOWN_LINT_LANGUAGES.includes(language),\n ) ?? fallbackLanguages;\n const customImports = standard.imports ?? [];\n const missingPresetLanguages = languages.filter((language) => !DEFAULT_CSPELL_IMPORTS[language]);\n\n if (missingPresetLanguages.length > 0 && customImports.length === 0) {\n throw new Error(\n `[ox-content] No bundled standard dictionary preset exists for ${missingPresetLanguages.join(\n \", \",\n )}. Provide dictionary.standard.imports to enable those languages.`,\n );\n }\n\n const imports = [\n ...languages\n .map((language) => DEFAULT_CSPELL_IMPORTS[language])\n .filter((value): value is string => Boolean(value)),\n ...customImports,\n ];\n\n if (imports.length === 0) {\n throw new Error(\n \"[ox-content] dictionary.standard requires at least one bundled preset language or custom import.\",\n );\n }\n\n return {\n imports: [...new Set(imports)],\n languages: [...new Set(languages)],\n provider: standard.provider ?? \"cspell\",\n resolveImportsRelativeTo: standard.resolveImportsRelativeTo ?? new URL(\".\", import.meta.url),\n };\n}\n\nasync function runStandardSpellcheckDocuments(\n maskedDocuments: string[],\n options: InternalNormalizedMarkdownLintOptions,\n): Promise<MarkdownLintDiagnostic[][]> {\n const standard = options.dictionary.standard;\n\n if (!standard || maskedDocuments.length === 0) {\n return maskedDocuments.map(() => []);\n }\n\n try {\n const { spellCheckDocument } = await loadCspellLib();\n const locale = standard.languages.join(\",\");\n const settings = createStandardSpellcheckSettings(options, locale);\n const spellCheckOptions = {\n generateSuggestions: true,\n noConfigSearch: true,\n numSuggestions: 3,\n resolveImportsRelativeTo: standard.resolveImportsRelativeTo,\n } satisfies SpellCheckFileOptions & { resolveImportsRelativeTo: string | URL };\n\n return Promise.all(\n maskedDocuments.map(async (maskedDocument, index) => {\n if (maskedDocument.trim().length === 0) {\n return [];\n }\n\n const result = await spellCheckDocument(\n {\n languageId: \"plaintext\",\n locale,\n text: maskedDocument,\n uri: `file:///ox-content-lint-${index}.md`,\n },\n spellCheckOptions,\n settings,\n );\n\n // Precompute the document's newline offsets once so each issue's line\n // can be resolved with a binary search instead of a fresh O(N) scan\n // from offset 0 (which made line resolution O(issues * length)).\n const newlineOffsets: number[] = [];\n for (let i = 0; i < maskedDocument.length; i++) {\n if (maskedDocument.charCodeAt(i) === 10) {\n newlineOffsets.push(i);\n }\n }\n\n return result.issues.map((issue) =>\n mapStandardIssueToDiagnostic(issue, standard.languages, newlineOffsets),\n );\n }),\n );\n } catch (error) {\n const imports = standard.imports.join(\", \");\n const message =\n imports.length > 0\n ? `[ox-content] Failed to load standard dictionaries from ${imports}. Verify the imports and install the referenced CSpell packages.`\n : \"[ox-content] Failed to load the configured standard dictionaries.\";\n\n throw new Error(message, {\n cause: error,\n });\n }\n}\n\nfunction createStandardSpellcheckSettings(\n options: InternalNormalizedMarkdownLintOptions,\n locale: string,\n): CSpellUserSettings {\n return {\n import: options.dictionary.standard ? options.dictionary.standard.imports : [],\n ignoreWords: options.dictionary.ignoredWords,\n language: locale,\n version: \"0.2\",\n words: [\n ...(options.dictionary.words ?? []),\n ...Object.values(options.dictionary.byLanguage ?? {}).flat(),\n ],\n };\n}\n\nasync function loadCspellLib(): Promise<typeof import(\"cspell-lib\")> {\n cspellLibPromise ??= import(\"cspell-lib\");\n return cspellLibPromise;\n}\n\nfunction mapStandardIssueToDiagnostic(\n issue: ValidationIssue,\n languages: MarkdownLintLanguage[],\n newlineOffsets: number[],\n): MarkdownLintDiagnostic {\n const line = getLineNumberAtOffset(newlineOffsets, issue.line.offset);\n const column = issue.offset - issue.line.offset + 1;\n const length = issue.length ?? issue.text.length;\n\n return {\n column,\n endColumn: column + length,\n endLine: line,\n language: inferStandardIssueLanguage(issue.text, languages),\n line,\n message: `Unknown word \"${issue.text}\".`,\n ruleId: \"spellcheck\",\n severity: \"warning\",\n suggestions: issue.suggestions?.slice(0, 3),\n };\n}\n\nfunction getLineNumberAtOffset(newlineOffsets: number[], offset: number): number {\n // Line number = 1 + (count of newline offsets strictly less than `offset`).\n // This matches the old linear scan exactly: a newline can only exist at an\n // index < text.length, so counting positions `< offset` over the whole\n // document gives the same count for every `offset` (including past EOF).\n let lo = 0;\n let hi = newlineOffsets.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (newlineOffsets[mid] < offset) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n\n return lo + 1;\n}\n\nfunction inferStandardIssueLanguage(\n word: string,\n languages: MarkdownLintLanguage[],\n): MarkdownLintLanguage | undefined {\n if (/[\\p{Script=Hiragana}\\p{Script=Katakana}]/u.test(word) && languages.includes(\"ja\")) {\n return \"ja\";\n }\n\n if (/[\\p{Script=Han}]/u.test(word)) {\n if (languages.includes(\"zh\") && !languages.includes(\"ja\")) {\n return \"zh\";\n }\n if (languages.includes(\"ja\") && !languages.includes(\"zh\")) {\n return \"ja\";\n }\n }\n\n if (/[\\p{Script=Latin}]/u.test(word)) {\n const latinLanguages = languages.filter(\n (language): language is Exclude<MarkdownLintLanguage, \"ja\" | \"zh\"> =>\n language !== \"ja\" && language !== \"zh\",\n );\n\n if (latinLanguages.length === 1) {\n return latinLanguages[0];\n }\n\n return inferLatinLanguageFromCharacters(word, latinLanguages);\n }\n\n return undefined;\n}\n\nfunction inferLatinLanguageFromCharacters(\n word: string,\n languages: Exclude<MarkdownLintLanguage, \"ja\" | \"zh\">[],\n): Exclude<MarkdownLintLanguage, \"ja\" | \"zh\"> | undefined {\n if (languages.includes(\"pl\") && /[ąćęłńóśźż]/iu.test(word)) {\n return \"pl\";\n }\n\n if (languages.includes(\"de\") && /[äöüß]/iu.test(word)) {\n return \"de\";\n }\n\n if (languages.includes(\"fr\") && /[àâæçéèêëîïôœùûüÿ]/iu.test(word)) {\n return \"fr\";\n }\n\n return undefined;\n}\n\nfunction summarizeDiagnostics(diagnostics: MarkdownLintDiagnostic[]): MarkdownLintResult {\n let errorCount = 0;\n let warningCount = 0;\n let infoCount = 0;\n\n for (const diagnostic of diagnostics) {\n if (diagnostic.severity === \"error\") {\n errorCount += 1;\n } else if (diagnostic.severity === \"warning\") {\n warningCount += 1;\n } else {\n infoCount += 1;\n }\n }\n\n return { diagnostics, errorCount, infoCount, warningCount };\n}\n\nfunction createEmptyLintResult(): MarkdownLintResult {\n return summarizeDiagnostics([]);\n}\n\nfunction sortDiagnostics(diagnostics: MarkdownLintDiagnostic[]): MarkdownLintDiagnostic[] {\n return [...diagnostics].sort((left, right) => {\n if (left.line !== right.line) {\n return left.line - right.line;\n }\n\n if (left.column !== right.column) {\n return left.column - right.column;\n }\n\n return left.ruleId.localeCompare(right.ruleId);\n });\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { glob } from \"glob\";\nimport {\n lintMarkdownDocumentsAsync,\n lintMarkdownAsync,\n type MarkdownLintDiagnostic,\n type MarkdownLintOptions,\n type MarkdownLintResult,\n} from \"./lint\";\n\nconst DEFAULT_LINT_FILE_INCLUDE = [\"**/*.md\", \"**/*.markdown\", \"**/*.mdx\"] as const;\nconst DEFAULT_LINT_FILE_EXCLUDE = [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\"] as const;\n\n/**\n * File-oriented Markdown lint options for end-user configuration.\n *\n * This extends the content-level lint options with project-level targeting,\n * so consumers can decide which files should be checked and which paths should\n * be ignored.\n */\nexport interface MarkdownLintFileOptions extends MarkdownLintOptions {\n /**\n * Base directory used to resolve `include` and `exclude` patterns.\n * @default process.cwd()\n */\n cwd?: string;\n\n /**\n * Glob patterns for files to lint.\n * @default ['**\\/*.md', '**\\/*.markdown', '**\\/*.mdx']\n */\n include?: string[];\n\n /**\n * Glob patterns for files to exclude from linting.\n * @default ['**\\/node_modules/**', '**\\/.git/**', '**\\/dist/**']\n */\n exclude?: string[];\n\n /**\n * Alias of `exclude`.\n */\n ignore?: string[];\n}\n\n/**\n * A lint diagnostic annotated with file metadata.\n */\nexport interface MarkdownLintFileDiagnostic extends MarkdownLintDiagnostic {\n filePath: string;\n relativePath: string;\n}\n\n/**\n * Lint result for a single file.\n */\nexport interface MarkdownLintFileResult extends MarkdownLintResult {\n filePath: string;\n relativePath: string;\n skipped: boolean;\n}\n\n/**\n * Aggregated lint result for multiple files.\n */\nexport interface MarkdownLintFilesResult {\n checkedFileCount: number;\n diagnostics: MarkdownLintFileDiagnostic[];\n errorCount: number;\n files: MarkdownLintFileResult[];\n infoCount: number;\n warningCount: number;\n}\n\ninterface ResolvedMarkdownLintFileOptions {\n cwd: string;\n exclude: string[];\n include: string[];\n lintOptions: MarkdownLintOptions;\n}\n\ninterface MarkdownLintFileEntry {\n filePath: string;\n relativePath: string;\n}\n\n/**\n * Returns true if the file path is included by the configured glob filters.\n */\nexport function shouldLintMarkdownFile(\n filePath: string,\n options: MarkdownLintFileOptions = {},\n): boolean {\n const resolvedOptions = resolveMarkdownLintFileOptions(options);\n return shouldLintAbsoluteFile(path.resolve(resolvedOptions.cwd, filePath), resolvedOptions);\n}\n\n/**\n * Lints a single Markdown file using project-style include/exclude settings.\n *\n * If the file is filtered out by `include` / `exclude`, the returned result is\n * marked as `skipped` and contains no diagnostics.\n */\nexport async function lintMarkdownFile(\n filePath: string,\n options: MarkdownLintFileOptions = {},\n): Promise<MarkdownLintFileResult> {\n const resolvedOptions = resolveMarkdownLintFileOptions(options);\n return lintMarkdownFileWithResolvedOptions(\n path.resolve(resolvedOptions.cwd, filePath),\n resolvedOptions,\n );\n}\n\n/**\n * Lints all Markdown files matched by the configured include/exclude patterns.\n */\nexport async function lintMarkdownFiles(\n options: MarkdownLintFileOptions = {},\n): Promise<MarkdownLintFilesResult> {\n const resolvedOptions = resolveMarkdownLintFileOptions(options);\n const matchedFiles = await collectMarkdownLintFileEntries(resolvedOptions);\n const sources = await Promise.all(\n matchedFiles.map((file) => fs.readFile(file.filePath, \"utf-8\")),\n );\n const results = await lintMarkdownDocumentsAsync(sources, resolvedOptions.lintOptions);\n\n const files = matchedFiles.map(\n (file, index): MarkdownLintFileResult => ({\n ...(results[index] ?? createEmptyLintResult()),\n filePath: file.filePath,\n relativePath: file.relativePath,\n skipped: false,\n }),\n );\n\n const diagnostics = files.flatMap((fileResult) =>\n fileResult.diagnostics.map(\n (diagnostic): MarkdownLintFileDiagnostic => ({\n ...diagnostic,\n filePath: fileResult.filePath,\n relativePath: fileResult.relativePath,\n }),\n ),\n );\n\n return {\n checkedFileCount: files.length,\n diagnostics,\n errorCount: files.reduce((count, fileResult) => count + fileResult.errorCount, 0),\n files,\n infoCount: files.reduce((count, fileResult) => count + fileResult.infoCount, 0),\n warningCount: files.reduce((count, fileResult) => count + fileResult.warningCount, 0),\n };\n}\n\nfunction resolveMarkdownLintFileOptions(\n options: MarkdownLintFileOptions,\n): ResolvedMarkdownLintFileOptions {\n return {\n cwd: path.resolve(options.cwd ?? process.cwd()),\n exclude: [\n ...new Set([...(options.exclude ?? DEFAULT_LINT_FILE_EXCLUDE), ...(options.ignore ?? [])]),\n ],\n include: [...new Set(options.include ?? DEFAULT_LINT_FILE_INCLUDE)],\n lintOptions: {\n dictionary: options.dictionary,\n languages: options.languages,\n rules: options.rules,\n },\n };\n}\n\nasync function lintMarkdownFileWithResolvedOptions(\n filePath: string,\n options: ResolvedMarkdownLintFileOptions,\n): Promise<MarkdownLintFileResult> {\n const absoluteFilePath = path.resolve(filePath);\n const relativePath = normalizePath(path.relative(options.cwd, absoluteFilePath));\n\n if (!shouldLintAbsoluteFile(absoluteFilePath, options)) {\n return {\n ...createEmptyLintResult(),\n filePath: absoluteFilePath,\n relativePath,\n skipped: true,\n };\n }\n\n const source = await fs.readFile(absoluteFilePath, \"utf-8\");\n const result = await lintMarkdownAsync(source, options.lintOptions);\n\n return {\n ...result,\n filePath: absoluteFilePath,\n relativePath,\n skipped: false,\n };\n}\n\nasync function collectMarkdownLintFileEntries(\n options: ResolvedMarkdownLintFileOptions,\n): Promise<MarkdownLintFileEntry[]> {\n const files = new Map<string, MarkdownLintFileEntry>();\n\n for (const pattern of options.include) {\n const matches = await glob(pattern, {\n absolute: true,\n cwd: options.cwd,\n ignore: options.exclude,\n nodir: true,\n });\n\n for (const filePath of matches) {\n const absoluteFilePath = path.resolve(filePath);\n if (shouldLintAbsoluteFile(absoluteFilePath, options)) {\n files.set(absoluteFilePath, {\n filePath: absoluteFilePath,\n relativePath: normalizePath(path.relative(options.cwd, absoluteFilePath)),\n });\n }\n }\n }\n\n return [...files.values()].sort((left, right) => left.filePath.localeCompare(right.filePath));\n}\n\nfunction shouldLintAbsoluteFile(\n filePath: string,\n options: ResolvedMarkdownLintFileOptions,\n): boolean {\n const absolutePath = normalizePath(path.resolve(filePath));\n const relativePath = normalizePath(path.relative(options.cwd, absolutePath));\n\n const matches = (patterns: string[]) =>\n patterns.some((pattern) => {\n const normalizedPattern = normalizePath(pattern);\n return (\n path.matchesGlob(relativePath, normalizedPattern) ||\n path.matchesGlob(absolutePath, normalizedPattern)\n );\n });\n\n return matches(options.include) && !matches(options.exclude);\n}\n\nfunction normalizePath(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n\nfunction createEmptyLintResult(): MarkdownLintResult {\n return {\n diagnostics: [],\n errorCount: 0,\n infoCount: 0,\n warningCount: 0,\n };\n}\n","/**\n * Custom JSX Runtime for Static HTML Generation\n *\n * This module provides a JSX runtime that outputs static HTML strings.\n * No React, no hydration, no client-side JavaScript - just pure HTML.\n *\n * @example\n * ```tsx\n * // tsconfig.json or vite.config.ts\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"@ox-content/vite-plugin\"\n * }\n * }\n *\n * // MyComponent.tsx\n * export function Hero({ title }: { title: string }) {\n * return (\n * <section class=\"hero\">\n * <h1>{title}</h1>\n * </section>\n * );\n * }\n * ```\n */\n\n// Self-closing tags that don't need closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n// Attributes that should be rendered as boolean\nconst BOOLEAN_ATTRS = new Set([\n \"allowfullscreen\",\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\",\n]);\n\n/**\n * Escapes HTML special characters to prevent XSS.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n\n/**\n * Converts a camelCase attribute name to kebab-case for HTML.\n * Special handling for data-* and aria-* attributes.\n */\nfunction toHtmlAttr(name: string): string {\n // className -> class\n if (name === \"className\") return \"class\";\n // htmlFor -> for\n if (name === \"htmlFor\") return \"for\";\n // Keep data-* and aria-* as-is\n if (name.startsWith(\"data\") || name.startsWith(\"aria\")) {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n return name;\n}\n\n/**\n * Renders an attribute value to a string.\n */\nfunction renderAttr(name: string, value: unknown): string {\n const htmlName = toHtmlAttr(name);\n\n // Skip undefined, null, and false values\n if (value === undefined || value === null || value === false) {\n return \"\";\n }\n\n // Boolean attributes\n if (BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}` : \"\";\n }\n\n // Style object to string\n if (name === \"style\" && typeof value === \"object\") {\n const styleStr = Object.entries(value as Record<string, string | number>)\n .map(([k, v]) => {\n const prop = k.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return `${prop}:${v}`;\n })\n .join(\";\");\n return ` style=\"${escapeHtml(styleStr)}\"`;\n }\n\n // Regular attribute\n return ` ${htmlName}=\"${escapeHtml(String(value as string | number | boolean))}\"`;\n}\n\n/**\n * JSX element type - either a string (intrinsic) or a function component.\n */\nexport type JSXElementType = string | ((props: Record<string, unknown>) => JSXNode);\n\n/**\n * Valid JSX child types.\n */\nexport type JSXChild = string | number | boolean | null | undefined | JSXNode | JSXChild[];\n\n/**\n * JSX node - the result of JSX expressions.\n */\nexport interface JSXNode {\n __html: string;\n}\n\n/**\n * Props with children.\n */\nexport interface JSXProps {\n children?: JSXChild;\n [key: string]: unknown;\n}\n\n/**\n * Renders children to HTML string.\n */\nfunction renderChildren(children: JSXChild): string {\n if (children === null || children === undefined || children === false) {\n return \"\";\n }\n\n if (children === true) {\n return \"\";\n }\n\n if (typeof children === \"string\") {\n return escapeHtml(children);\n }\n\n if (typeof children === \"number\") {\n return String(children);\n }\n\n if (Array.isArray(children)) {\n return children.map(renderChildren).join(\"\");\n }\n\n if (typeof children === \"object\" && \"__html\" in children) {\n return children.__html;\n }\n\n return \"\";\n}\n\n/**\n * Creates a JSX element.\n * This is the core function called by the JSX transform.\n */\nexport function jsx(type: JSXElementType, props: JSXProps, _key?: string): JSXNode {\n const { children, ...restProps } = props;\n\n // Function component\n if (typeof type === \"function\") {\n return type({ ...restProps, children });\n }\n\n // Intrinsic element (HTML tag)\n const tag = type;\n let html = `<${tag}`;\n\n // Render attributes\n for (const [name, value] of Object.entries(restProps)) {\n // Skip internal props\n if (name === \"key\" || name === \"ref\") continue;\n html += renderAttr(name, value);\n }\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tag)) {\n html += \" />\";\n return { __html: html };\n }\n\n html += \">\";\n\n // Render children\n if (children !== undefined) {\n html += renderChildren(children);\n }\n\n html += `</${tag}>`;\n\n return { __html: html };\n}\n\n/**\n * Creates a JSX element with static children.\n * Called by the JSX transform for elements with multiple children.\n */\nexport function jsxs(type: JSXElementType, props: JSXProps, key?: string): JSXNode {\n return jsx(type, props, key);\n}\n\n/**\n * Fragment component - renders children without a wrapper element.\n */\nexport function Fragment({ children }: { children?: JSXChild }): JSXNode {\n return { __html: renderChildren(children) };\n}\n\n/**\n * Renders a JSX node to an HTML string.\n */\nexport function renderToString(node: JSXNode): string {\n return node.__html;\n}\n\n/**\n * Creates raw HTML without escaping.\n * Use with caution - only for trusted content.\n *\n * @example\n * ```tsx\n * <div>{raw('<strong>Bold</strong>')}</div>\n * ```\n */\nexport function raw(html: string): JSXNode {\n return { __html: html };\n}\n\n/**\n * Conditionally renders content.\n *\n * @example\n * ```tsx\n * {when(isLoggedIn, <UserMenu />)}\n * ```\n */\nexport function when(condition: boolean, content: JSXNode): JSXNode {\n return condition ? content : { __html: \"\" };\n}\n\n/**\n * Maps over an array and renders each item.\n *\n * @example\n * ```tsx\n * {each(items, (item) => <li>{item.name}</li>)}\n * ```\n */\nexport function each<T>(items: T[], render: (item: T, index: number) => JSXNode): JSXNode {\n const html = items.map((item, i) => render(item, i).__html).join(\"\");\n return { __html: html };\n}\n\n// Default export for convenience\nexport default {\n jsx,\n jsxs,\n Fragment,\n renderToString,\n raw,\n when,\n each,\n};\n","/**\n * Page Context for Static HTML Generation\n *\n * Provides a way to access page props (frontmatter, content, etc.)\n * from theme components during static rendering.\n *\n * @example\n * ```tsx\n * // theme/Layout.tsx\n * import { usePageProps, PageProps } from '@ox-content/vite-plugin';\n *\n * export function Layout({ children }: { children: JSX.Element }) {\n * const page = usePageProps<MyPageProps>();\n * return (\n * <html>\n * <head>\n * <title>{page.title}</title>\n * </head>\n * <body>\n * <header>{page.title}</header>\n * <main>{children}</main>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\n\nimport type { TocEntry } from \"./types\";\n\n/**\n * Base page props available for all pages.\n */\nexport interface BasePageProps {\n /** Page title from frontmatter or first heading */\n title: string;\n /** Page description from frontmatter */\n description?: string;\n /** Rendered HTML content */\n html: string;\n /** Table of contents entries */\n toc: TocEntry[];\n /** Last git commit timestamp in milliseconds */\n lastUpdated?: number;\n /** Source file path (relative to docs root) */\n path: string;\n /** Output URL path */\n url: string;\n /** Raw frontmatter object */\n frontmatter: Record<string, unknown>;\n /** Layout name from frontmatter */\n layout?: string;\n}\n\n/**\n * Extended page props with custom frontmatter.\n */\nexport type PageProps<T extends Record<string, unknown> = Record<string, unknown>> =\n BasePageProps & {\n /** Custom frontmatter fields */\n frontmatter: T & Record<string, unknown>;\n };\n\n/**\n * Site-wide configuration available in context.\n */\nexport interface SiteConfig {\n /** Site name */\n name: string;\n /** Base URL path */\n base: string;\n /** All pages in the site */\n pages: BasePageProps[];\n /** Navigation groups */\n nav: NavGroup[];\n}\n\n/**\n * Navigation group.\n */\nexport interface NavGroup {\n title: string;\n items: NavItem[];\n}\n\n/**\n * Navigation item.\n */\nexport interface NavItem {\n title: string;\n path: string;\n href: string;\n}\n\n/**\n * Complete render context.\n */\nexport interface RenderContext<T extends Record<string, unknown> = Record<string, unknown>> {\n /** Current page props */\n page: PageProps<T>;\n /** Site configuration */\n site: SiteConfig;\n}\n\n// Internal context storage (set during render)\nlet currentContext: RenderContext | null = null;\n\n/**\n * Sets the current render context.\n * Called internally during page rendering.\n * @internal\n */\nexport function setRenderContext(ctx: RenderContext): void {\n currentContext = ctx;\n}\n\n/**\n * Clears the current render context.\n * Called internally after page rendering.\n * @internal\n */\nexport function clearRenderContext(): void {\n currentContext = null;\n}\n\n/**\n * Gets the current page props.\n *\n * @returns The current page props\n * @throws Error if called outside of a render context\n *\n * @example\n * ```tsx\n * function PageTitle() {\n * const page = usePageProps();\n * return <h1>{page.title}</h1>;\n * }\n * ```\n */\nexport function usePageProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): PageProps<T> {\n if (!currentContext) {\n throw new Error(\n \"[ox-content] usePageProps() must be called during page rendering. \" +\n \"Make sure you are using it inside a theme component.\",\n );\n }\n return currentContext.page as PageProps<T>;\n}\n\n/**\n * Gets the site configuration.\n *\n * @returns The site configuration\n * @throws Error if called outside of a render context\n *\n * @example\n * ```tsx\n * function SiteHeader() {\n * const site = useSiteConfig();\n * return <header>{site.name}</header>;\n * }\n * ```\n */\nexport function useSiteConfig(): SiteConfig {\n if (!currentContext) {\n throw new Error(\n \"[ox-content] useSiteConfig() must be called during page rendering. \" +\n \"Make sure you are using it inside a theme component.\",\n );\n }\n return currentContext.site;\n}\n\n/**\n * Gets the full render context.\n *\n * @returns The complete render context\n * @throws Error if called outside of a render context\n *\n * @example\n * ```tsx\n * function Layout({ children }) {\n * const ctx = useRenderContext();\n * return (\n * <html>\n * <head><title>{ctx.page.title} - {ctx.site.name}</title></head>\n * <body>{children}</body>\n * </html>\n * );\n * }\n * ```\n */\nexport function useRenderContext<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): RenderContext<T> {\n if (!currentContext) {\n throw new Error(\n \"[ox-content] useRenderContext() must be called during page rendering. \" +\n \"Make sure you are using it inside a theme component.\",\n );\n }\n return currentContext as RenderContext<T>;\n}\n\n/**\n * Gets the navigation groups.\n *\n * @example\n * ```tsx\n * function Sidebar() {\n * const nav = useNav();\n * return (\n * <nav>\n * {each(nav, (group) => (\n * <div>\n * <h3>{group.title}</h3>\n * <ul>\n * {each(group.items, (item) => (\n * <li><a href={item.href}>{item.title}</a></li>\n * ))}\n * </ul>\n * </div>\n * ))}\n * </nav>\n * );\n * }\n * ```\n */\nexport function useNav(): NavGroup[] {\n return useSiteConfig().nav;\n}\n\n/**\n * Checks if the given path is the current page.\n *\n * @example\n * ```tsx\n * function NavLink({ href, children }) {\n * const isActive = useIsActive(href);\n * return <a href={href} class={isActive ? 'active' : ''}>{children}</a>;\n * }\n * ```\n */\nexport function useIsActive(path: string): boolean {\n const page = usePageProps();\n return page.path === path || page.url === path;\n}\n\n// Type generation helpers\n\n/**\n * Schema for frontmatter type generation.\n */\nexport interface FrontmatterSchema {\n /** Field name */\n name: string;\n /** TypeScript type */\n type: string;\n /** Whether the field is optional */\n optional: boolean;\n /** JSDoc description */\n description?: string;\n}\n\n/**\n * Infers TypeScript types from frontmatter values.\n */\nexport function inferType(value: unknown): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"undefined\";\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (Array.isArray(value)) {\n if (value.length === 0) return \"unknown[]\";\n const itemTypes = [...new Set(value.map(inferType))];\n if (itemTypes.length === 1) return `${itemTypes[0]}[]`;\n return `(${itemTypes.join(\" | \")})[]`;\n }\n if (typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length === 0) return \"Record<string, unknown>\";\n const props = entries.map(([k, v]) => `${k}: ${inferType(v)}`).join(\"; \");\n return `{ ${props} }`;\n }\n return \"unknown\";\n}\n\n/**\n * Generates TypeScript interface from frontmatter samples.\n */\nexport function generateFrontmatterTypes(\n samples: Record<string, unknown>[],\n interfaceName = \"PageFrontmatter\",\n): string {\n // Collect all fields and their types across all samples\n const fields = new Map<string, { types: Set<string>; count: number }>();\n\n for (const sample of samples) {\n for (const [key, value] of Object.entries(sample)) {\n const existing = fields.get(key) ?? { types: new Set(), count: 0 };\n existing.types.add(inferType(value));\n existing.count++;\n fields.set(key, existing);\n }\n }\n\n // Generate interface\n const lines: string[] = [\n \"/**\",\n \" * Auto-generated frontmatter type based on your pages.\",\n \" * DO NOT EDIT - this file is generated by ox-content.\",\n \" */\",\n \"\",\n `export interface ${interfaceName} {`,\n ];\n\n for (const [name, { types, count }] of fields) {\n const isOptional = count < samples.length;\n const typeStr = [...types].join(\" | \");\n const optionalMark = isOptional ? \"?\" : \"\";\n lines.push(` ${name}${optionalMark}: ${typeStr};`);\n }\n\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\n `export type PageProps = import('@ox-content/vite-plugin').PageProps<${interfaceName}>;`,\n );\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n","/**\n * Theme Renderer for Static HTML Generation\n *\n * Renders JSX theme components to static HTML strings.\n * No client-side JavaScript is included by default.\n */\n\nimport { renderToString, raw, type JSXNode } from \"./jsx-runtime\";\nimport {\n setRenderContext,\n clearRenderContext,\n generateFrontmatterTypes,\n type RenderContext,\n type PageProps,\n type SiteConfig,\n type NavGroup,\n} from \"./page-context\";\nimport type { TocEntry } from \"./types\";\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Theme component type.\n */\nexport type ThemeComponent = (props: ThemeProps) => JSXNode;\n\n/**\n * Props passed to the theme component.\n */\nexport interface ThemeProps {\n /** Rendered page content as JSX */\n children: JSXNode;\n}\n\n/**\n * Page data for rendering.\n */\nexport interface PageData {\n /** Page title */\n title: string;\n /** Page description */\n description?: string;\n /** Rendered HTML content */\n html: string;\n /** Table of contents */\n toc: TocEntry[];\n /** Last git commit timestamp in milliseconds */\n lastUpdated?: number;\n /** Source file path */\n path: string;\n /** Output URL path */\n url: string;\n /** Frontmatter */\n frontmatter: Record<string, unknown>;\n /** Layout name */\n layout?: string;\n}\n\n/**\n * Theme render options.\n */\nexport interface ThemeRenderOptions {\n /** Theme component to use */\n theme: ThemeComponent;\n /** Site name */\n siteName: string;\n /** Base URL path */\n base: string;\n /** Navigation groups */\n nav: NavGroup[];\n /** All pages (for site context) */\n pages: PageData[];\n /** Output directory for type definitions */\n typesOutDir?: string;\n}\n\n/**\n * Renders a page using the theme component.\n *\n * @param page - Page data to render\n * @param options - Theme render options\n * @returns Rendered HTML string\n */\nexport function renderPage(page: PageData, options: ThemeRenderOptions): string {\n const { theme, siteName, base, nav, pages } = options;\n\n // Build page props\n const pageProps: PageProps = {\n title: page.title,\n description: page.description,\n html: page.html,\n toc: page.toc,\n lastUpdated: page.lastUpdated,\n path: page.path,\n url: page.url,\n frontmatter: page.frontmatter,\n layout: page.layout,\n };\n\n // Build site config\n const siteConfig: SiteConfig = {\n name: siteName,\n base,\n nav,\n pages: pages.map((p) => ({\n title: p.title,\n description: p.description,\n html: p.html,\n toc: p.toc,\n lastUpdated: p.lastUpdated,\n path: p.path,\n url: p.url,\n frontmatter: p.frontmatter,\n layout: p.layout,\n })),\n };\n\n // Set render context\n const context: RenderContext = {\n page: pageProps,\n site: siteConfig,\n };\n\n setRenderContext(context);\n\n try {\n // Render theme with page content\n const contentNode = raw(page.html);\n const result = theme({ children: contentNode });\n\n // Get HTML string\n const html = renderToString(result);\n\n // Add doctype if not present\n if (!html.trimStart().toLowerCase().startsWith(\"<!doctype\")) {\n return `<!DOCTYPE html>\\n${html}`;\n }\n\n return html;\n } finally {\n clearRenderContext();\n }\n}\n\n/**\n * Renders all pages and generates type definitions.\n *\n * @param pages - All pages to render\n * @param options - Theme render options\n * @returns Map of output paths to rendered HTML\n */\nexport async function renderAllPages(\n pages: PageData[],\n options: ThemeRenderOptions,\n): Promise<Map<string, string>> {\n const results = new Map<string, string>();\n\n // Render each page\n for (const page of pages) {\n const html = renderPage(page, { ...options, pages });\n results.set(page.url, html);\n }\n\n // Generate type definitions if output directory is specified\n if (options.typesOutDir) {\n await generateTypes(pages, options.typesOutDir);\n }\n\n return results;\n}\n\n/**\n * Generates TypeScript type definitions from page frontmatter.\n *\n * @param pages - All pages\n * @param outDir - Output directory for types\n */\nexport async function generateTypes(pages: PageData[], outDir: string): Promise<void> {\n // Collect all frontmatter samples\n const samples = pages.map((p) => p.frontmatter);\n\n // Generate types\n const types = generateFrontmatterTypes(samples);\n\n // Write to file\n const typesPath = join(outDir, \"page-props.d.ts\");\n await mkdir(dirname(typesPath), { recursive: true });\n await writeFile(typesPath, types, \"utf-8\");\n}\n\n/**\n * Default theme component.\n * A minimal theme that renders page content with basic styling.\n */\nexport function DefaultTheme({ children }: ThemeProps): JSXNode {\n // Use hooks inside the component\n const { usePageProps, useSiteConfig } = require(\"./page-context\");\n const page = usePageProps();\n const site = useSiteConfig();\n\n return {\n __html: `<!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(page.title)} - ${escapeHtml(site.name)}</title>\n ${page.description ? `<meta name=\"description\" content=\"${escapeHtml(page.description)}\">` : \"\"}\n <style>\n :root {\n --octc-color-primary: #4f6fae;\n --octc-color-text: #131a30;\n --octc-color-bg: #ffffff;\n --octc-color-bg-alt: #f5f7fb;\n --octc-color-text-muted: #4f607b;\n --octc-color-border: #d2dbea;\n }\n body {\n font-family: \"IBM Plex Sans\", \"Avenir Next\", \"Segoe UI Variable\", \"Segoe UI\", sans-serif;\n line-height: 1.7;\n color: var(--octc-color-text);\n background: var(--octc-color-bg);\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n }\n a { color: var(--octc-color-primary); }\n </style>\n</head>\n<body>\n <header>\n <h1>${escapeHtml(site.name)}</h1>\n </header>\n <main>\n ${children.__html}\n </main>\n</body>\n</html>`,\n };\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\n/**\n * Creates a theme with layout switching support.\n *\n * @example\n * ```tsx\n * import { createTheme } from '@ox-content/vite-plugin';\n * import { DefaultLayout } from './layouts/Default';\n * import { EntryLayout } from './layouts/Entry';\n *\n * export default createTheme({\n * layouts: {\n * default: DefaultLayout,\n * entry: EntryLayout,\n * },\n * });\n * ```\n */\nexport function createTheme(config: {\n layouts: Record<string, ThemeComponent>;\n defaultLayout?: string;\n}): ThemeComponent {\n const { layouts, defaultLayout = \"default\" } = config;\n\n return function ThemeWithLayouts({ children }: ThemeProps): JSXNode {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { usePageProps } = require(\"./page-context\");\n const page = usePageProps();\n\n // Get layout from frontmatter or use default\n const layoutName = page.layout ?? defaultLayout;\n const Layout = layouts[layoutName] ?? layouts[defaultLayout];\n\n if (!Layout) {\n throw new Error(\n `[ox-content] Layout \"${layoutName}\" not found. ` +\n `Available layouts: ${Object.keys(layouts).join(\", \")}`,\n );\n }\n\n return Layout({ children });\n };\n}\n","/**\n * Vite Plugin for Ox Content\n *\n * Uses Vite's Environment API for SSG-focused Markdown processing.\n * Provides separate environments for client and server rendering.\n */\n\nimport * as path from \"path\";\nimport type { Plugin, ViteDevServer, ResolvedConfig } from \"vite\";\nimport { createMarkdownEnvironment } from \"./environment\";\nimport { transformMarkdown } from \"./transform\";\nimport { extractDocs, generateMarkdown, writeDocs, resolveDocsOptions } from \"./docs\";\nimport { buildSsg, resolveSsgOptions } from \"./ssg\";\nimport {\n resolveSearchOptions,\n buildSearchIndex,\n writeSearchIndex,\n generateSearchModule,\n} from \"./search\";\nimport { resolveOgImageOptions } from \"./og-image\";\nimport {\n createDevServerMiddleware,\n createDevServerCache,\n invalidateNavCache,\n invalidatePageCache,\n} from \"./dev-server\";\nimport { createOgViewerPlugin } from \"./og-viewer\";\nimport { resolveI18nOptions, createI18nPlugin } from \"./i18n\";\nimport { isMarkdownFilePath, normalizeMarkdownExtensions } from \"./markdown\";\nimport type { BuiltinPmOptions, OxContentOptions, ResolvedOptions } from \"./types\";\n\nexport type { OxContentOptions } from \"./types\";\nexport type { LanguageRegistration, ThemeRegistration } from \"shiki\";\nexport type {\n CodeAnnotationSyntax,\n CodeAnnotationsOptions,\n ResolvedCodeAnnotationsOptions,\n WikiLinkOptions,\n ResolvedWikiLinkOptions,\n EmojiShortcodeOptions,\n ResolvedEmojiShortcodeOptions,\n AttrsOptions,\n ResolvedAttrsOptions,\n CodeImportOptions,\n ResolvedCodeImportOptions,\n SanitizeOptions,\n ResolvedSanitizeOptions,\n EditThisPageOptions,\n ResolvedEditThisPageOptions,\n CodeBlockLintOptions,\n ResolvedCodeBlockLintOptions,\n CodeBlockTypecheckOptions,\n ResolvedCodeBlockTypecheckOptions,\n DocsTestOptions,\n ResolvedDocsTestOptions,\n DocsOptions,\n ResolvedDocsOptions,\n DocEntry,\n ParamDoc,\n ReturnDoc,\n ExtractedDocs,\n SsgOptions,\n ResolvedSsgOptions,\n SearchOptions,\n ResolvedSearchOptions,\n SearchDocument,\n SearchResult,\n // Entry page types\n HeroAction,\n HeroImage,\n HeroConfig,\n FeatureConfig,\n EntryPageConfig,\n SsgNavigationItem,\n SsgNavigationGroup,\n // i18n types\n I18nOptions,\n ResolvedI18nOptions,\n LocaleConfig,\n BuiltinEmbedOptions,\n ResolvedBuiltinEmbedOptions,\n BuiltinPmOptions,\n} from \"./types\";\n\n/**\n * Creates the Ox Content Vite plugin.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { oxContent } from '@ox-content/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * oxContent({\n * srcDir: 'content',\n * gfm: true,\n * }),\n * ],\n * });\n * ```\n */\nexport function oxContent(options: OxContentOptions = {}): Plugin[] {\n const resolvedOptions = resolveOptions(options);\n let config: ResolvedConfig | undefined;\n const getRoot = () => config?.root || process.cwd();\n\n const ssgDevCache = createDevServerCache();\n const plugins: Plugin[] = [\n createMainPlugin(resolvedOptions, (resolvedConfig) => {\n config = resolvedConfig;\n }),\n createEnvironmentPlugin(resolvedOptions),\n createDocsPlugin(resolvedOptions, getRoot),\n createSsgPlugin(resolvedOptions, getRoot, ssgDevCache),\n createSearchPlugin(resolvedOptions, getRoot),\n ];\n\n if (resolvedOptions.i18n) {\n plugins.push(createI18nPlugin(resolvedOptions));\n }\n\n if (resolvedOptions.ogViewer) {\n plugins.push(createOgViewerPlugin(resolvedOptions));\n }\n\n return plugins;\n}\n\nasync function regenerateDocs(resolvedOptions: ResolvedOptions, root: string): Promise<number> {\n const docsOptions = resolvedOptions.docs;\n if (!docsOptions || !docsOptions.enabled) {\n return 0;\n }\n\n const srcDirs = docsOptions.src.map((src) => path.resolve(root, src));\n const outDir = path.resolve(root, docsOptions.out);\n const extracted = await extractDocs(srcDirs, docsOptions);\n const generated = generateMarkdown(extracted, docsOptions);\n\n await writeDocs(generated, outDir, extracted, docsOptions);\n\n return Object.keys(generated).length;\n}\n\nfunction createMainPlugin(\n resolvedOptions: ResolvedOptions,\n setConfig: (config: ResolvedConfig) => void,\n): Plugin {\n return {\n name: \"ox-content\",\n\n configResolved: setConfig,\n\n configureServer(devServer) {\n devServer.middlewares.use(async (req, res, next) => {\n const url = req.url;\n if (!url || !isMarkdownFilePath(url, resolvedOptions.extensions)) {\n return next();\n }\n\n next();\n });\n },\n\n resolveId(id) {\n if (id.startsWith(\"virtual:ox-content/\")) {\n return \"\\0\" + id;\n }\n\n if (isMarkdownFilePath(id, resolvedOptions.extensions)) {\n return id;\n }\n\n return null;\n },\n\n async load(id) {\n if (id.startsWith(\"\\0virtual:ox-content/\")) {\n const virtualPath = id.slice(\"\\0virtual:ox-content/\".length);\n return generateVirtualModule(virtualPath, resolvedOptions);\n }\n\n return null;\n },\n\n async transform(code, id) {\n if (!isMarkdownFilePath(id, resolvedOptions.extensions)) {\n return null;\n }\n\n const result = await transformMarkdown(code, id, resolvedOptions);\n return {\n code: result.code,\n map: null,\n };\n },\n\n async handleHotUpdate({ file, server }) {\n if (!isMarkdownFilePath(file, resolvedOptions.extensions)) {\n return;\n }\n\n server.ws.send({\n type: \"custom\",\n event: \"ox-content:update\",\n data: { file },\n });\n\n const modules = server.moduleGraph.getModulesByFile(file);\n return modules ? Array.from(modules) : [];\n },\n };\n}\n\nfunction createEnvironmentPlugin(resolvedOptions: ResolvedOptions): Plugin {\n return {\n name: \"ox-content:environment\",\n\n config() {\n return {\n environments: {\n markdown: createMarkdownEnvironment(resolvedOptions),\n },\n };\n },\n };\n}\n\nfunction createDocsPlugin(resolvedOptions: ResolvedOptions, getRoot: () => string): Plugin {\n return {\n name: \"ox-content:docs\",\n\n async buildStart() {\n const docsOptions = resolvedOptions.docs;\n if (!docsOptions || !docsOptions.enabled) {\n return;\n }\n\n try {\n const count = await regenerateDocs(resolvedOptions, getRoot());\n console.log(`[ox-content] Generated ${count} documentation files to ${docsOptions.out}`);\n } catch (err) {\n console.warn(\"[ox-content] Failed to generate documentation:\", err);\n }\n },\n\n configureServer(devServer) {\n const docsOptions = resolvedOptions.docs;\n if (!docsOptions || !docsOptions.enabled) {\n return;\n }\n\n const root = getRoot();\n const srcDirs = docsOptions.src.map((src) => path.resolve(root, src));\n for (const srcDir of srcDirs) {\n devServer.watcher.add(srcDir);\n }\n\n devServer.watcher.on(\"all\", async (event, file) => {\n if (event !== \"add\" && event !== \"change\" && event !== \"unlink\") {\n return;\n }\n\n const isSourceFile = srcDirs.some(\n (srcDir) => file.startsWith(srcDir) && (file.endsWith(\".ts\") || file.endsWith(\".tsx\")),\n );\n if (!isSourceFile) {\n return;\n }\n\n try {\n await regenerateDocs(resolvedOptions, root);\n } catch {\n // Ignore errors during dev.\n }\n });\n },\n };\n}\n\nfunction createSsgPlugin(\n resolvedOptions: ResolvedOptions,\n getRoot: () => string,\n ssgDevCache: ReturnType<typeof createDevServerCache>,\n): Plugin {\n return {\n name: \"ox-content:ssg\",\n\n configureServer(devServer) {\n const ssgOptions = resolvedOptions.ssg;\n if (!ssgOptions.enabled) return;\n\n const root = getRoot();\n const srcDir = path.resolve(root, resolvedOptions.srcDir);\n devServer.middlewares.use(createDevServerMiddleware(resolvedOptions, root, ssgDevCache));\n\n devServer.watcher.on(\"add\", (file: string) => {\n notifySsgFileAddedOrRemoved(devServer, resolvedOptions, ssgDevCache, srcDir, file, \"add\");\n });\n devServer.watcher.on(\"unlink\", (file: string) => {\n notifySsgFileAddedOrRemoved(\n devServer,\n resolvedOptions,\n ssgDevCache,\n srcDir,\n file,\n \"unlink\",\n );\n });\n devServer.watcher.on(\"change\", (file: string) => {\n if (file.startsWith(srcDir) && isMarkdownFilePath(file, resolvedOptions.extensions)) {\n invalidatePageCache(ssgDevCache, file);\n }\n });\n },\n\n async closeBundle() {\n const ssgOptions = resolvedOptions.ssg;\n if (!ssgOptions.enabled) {\n return;\n }\n\n try {\n const result = await buildSsg(resolvedOptions, getRoot());\n if (result.files.length > 0) {\n console.log(`[ox-content] Generated ${result.files.length} output files`);\n }\n\n for (const error of result.errors) {\n console.warn(`[ox-content] ${error}`);\n }\n } catch (err) {\n console.error(\"[ox-content] SSG build failed:\", err);\n }\n },\n };\n}\n\nfunction notifySsgFileAddedOrRemoved(\n devServer: ViteDevServer,\n resolvedOptions: ResolvedOptions,\n ssgDevCache: ReturnType<typeof createDevServerCache>,\n srcDir: string,\n file: string,\n type: \"add\" | \"unlink\",\n): void {\n if (!file.startsWith(srcDir) || !isMarkdownFilePath(file, resolvedOptions.extensions)) {\n return;\n }\n\n invalidateNavCache(ssgDevCache);\n devServer.ws.send({\n type: \"custom\",\n event: \"ox-content:update\",\n data: { file, type },\n });\n}\n\nfunction createSearchPlugin(resolvedOptions: ResolvedOptions, getRoot: () => string): Plugin {\n let searchIndexJson = \"\";\n\n return {\n name: \"ox-content:search\",\n\n resolveId(id) {\n if (id === \"virtual:ox-content/search\") {\n return \"\\0virtual:ox-content/search\";\n }\n return null;\n },\n\n async load(id) {\n if (id !== \"\\0virtual:ox-content/search\") {\n return null;\n }\n\n const searchOptions = resolvedOptions.search;\n if (!searchOptions.enabled) {\n return \"export const search = () => []; export const searchOptions = { enabled: false }; export default { search, searchOptions };\";\n }\n\n const indexPath = resolvedOptions.base + \"search-index.json\";\n return generateSearchModule(searchOptions, indexPath);\n },\n\n async buildStart() {\n const searchOptions = resolvedOptions.search;\n if (!searchOptions.enabled) {\n return;\n }\n\n const srcDir = path.resolve(getRoot(), resolvedOptions.srcDir);\n try {\n searchIndexJson = await buildSearchIndex(\n srcDir,\n resolvedOptions.base,\n resolvedOptions.extensions,\n );\n console.log(\"[ox-content] Search index built\");\n } catch (err) {\n console.warn(\"[ox-content] Failed to build search index:\", err);\n }\n },\n\n async closeBundle() {\n const searchOptions = resolvedOptions.search;\n if (!searchOptions.enabled || !searchIndexJson) {\n return;\n }\n\n const outDir = path.resolve(getRoot(), resolvedOptions.outDir);\n try {\n await writeSearchIndex(searchIndexJson, outDir);\n console.log(\"[ox-content] Search index written to\", path.join(outDir, \"search-index.json\"));\n } catch (err) {\n console.warn(\"[ox-content] Failed to write search index:\", err);\n }\n },\n };\n}\n\n/**\n * Resolves plugin options with defaults.\n */\nfunction resolveOptions(options: OxContentOptions): ResolvedOptions {\n return {\n srcDir: options.srcDir ?? \"content\",\n outDir: options.outDir ?? \"dist\",\n base: options.base ?? \"/\",\n extensions: normalizeMarkdownExtensions(options.extensions),\n ssg: resolveSsgOptions(options.ssg),\n gfm: options.gfm ?? true,\n footnotes: options.footnotes ?? true,\n tables: options.tables ?? true,\n taskLists: options.taskLists ?? true,\n strikethrough: options.strikethrough ?? true,\n highlight: options.highlight ?? false,\n highlightTheme: options.highlightTheme ?? \"github-dark\",\n highlightLangs: options.highlightLangs ?? [],\n codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),\n wikiLinks: resolveWikiLinkOptions(options.wikiLinks, options.base ?? \"/\"),\n emojiShortcodes: resolveEmojiShortcodeOptions(options.emojiShortcodes),\n attrs: resolveAttrsOptions(options.attrs),\n codeImports: resolveCodeImportOptions(options.codeImports),\n sanitize: resolveSanitizeOptions(options.sanitize),\n editThisPage: resolveEditThisPageOptions(options.editThisPage),\n cjkEmphasis: options.cjkEmphasis ?? false,\n codeBlockLint: resolveCodeBlockLintOptions(options.codeBlockLint),\n codeBlockTypecheck: resolveCodeBlockTypecheckOptions(options.codeBlockTypecheck),\n docsTests: resolveDocsTestOptions(options.docsTests),\n mermaid: options.mermaid ?? false,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n ogImage: options.ogImage ?? false,\n ogImageOptions: resolveOgImageOptions(options.ogImageOptions),\n transformers: options.transformers ?? [],\n docs: resolveDocsOptions(options.docs),\n search: resolveSearchOptions(options.search),\n ogViewer: options.ogViewer ?? true,\n embeds: resolveBuiltinEmbedOptions(options.embeds),\n i18n: resolveI18nOptions(options.i18n),\n };\n}\n\nexport function resolveBuiltinEmbedOptions(\n options: OxContentOptions[\"embeds\"],\n): ResolvedOptions[\"embeds\"] {\n if (options === false) {\n return {\n github: false,\n openGraph: false,\n pm: false,\n spotify: false,\n stackBlitz: false,\n twitter: false,\n bluesky: false,\n webContainer: false,\n };\n }\n\n return {\n github: resolveSingleEmbedOptions(options?.github),\n openGraph: resolveSingleEmbedOptions(options?.openGraph),\n pm: resolvePmOptions(options?.pm),\n spotify: options?.spotify === true,\n stackBlitz: options?.stackBlitz === true,\n twitter: options?.twitter === true,\n bluesky: options?.bluesky === true,\n webContainer: options?.webContainer === true,\n };\n}\n\nfunction resolveSingleEmbedOptions<T extends object>(options: boolean | T | undefined): T | false {\n if (options === false) return false;\n if (options === true || options === undefined) return {} as T;\n return options;\n}\n\nfunction resolvePmOptions(\n options: boolean | BuiltinPmOptions | undefined,\n): BuiltinPmOptions | false {\n if (options === false || options === undefined) return false;\n if (options === true) return {};\n return options;\n}\n\nfunction resolveWikiLinkOptions(\n options: OxContentOptions[\"wikiLinks\"],\n baseUrl: string,\n): ResolvedOptions[\"wikiLinks\"] {\n if (!options) return { enabled: false, baseUrl };\n if (options === true) return { enabled: true, baseUrl };\n return { enabled: true, baseUrl: options.baseUrl ?? baseUrl };\n}\n\nfunction resolveEmojiShortcodeOptions(\n options: OxContentOptions[\"emojiShortcodes\"],\n): ResolvedOptions[\"emojiShortcodes\"] {\n if (!options) return { enabled: false, custom: {} };\n if (options === true) return { enabled: true, custom: {} };\n return { enabled: true, custom: options.custom ?? {} };\n}\n\nfunction resolveAttrsOptions(options: OxContentOptions[\"attrs\"]): ResolvedOptions[\"attrs\"] {\n if (!options) return { enabled: false };\n if (options === true) return { enabled: true };\n return { enabled: options.enabled ?? true };\n}\n\nfunction resolveCodeImportOptions(\n options: OxContentOptions[\"codeImports\"],\n): ResolvedOptions[\"codeImports\"] {\n if (!options) return { enabled: false };\n if (options === true) return { enabled: true };\n return { enabled: true, rootDir: options.rootDir };\n}\n\nfunction resolveSanitizeOptions(\n options: OxContentOptions[\"sanitize\"],\n): ResolvedOptions[\"sanitize\"] {\n if (!options) return { enabled: false };\n if (options === true) return { enabled: true };\n return {\n enabled: true,\n allowedTags: options.allowedTags,\n allowedAttributes: options.allowedAttributes,\n allowedUrlSchemes: options.allowedUrlSchemes,\n };\n}\n\nfunction resolveEditThisPageOptions(\n options: OxContentOptions[\"editThisPage\"],\n): ResolvedOptions[\"editThisPage\"] {\n if (!options) return { enabled: false, branch: \"main\", label: \"Edit this page\" };\n if (options === true) return { enabled: false, branch: \"main\", label: \"Edit this page\" };\n return {\n enabled: Boolean(options.repoUrl),\n repoUrl: options.repoUrl,\n branch: options.branch ?? \"main\",\n rootDir: options.rootDir,\n label: options.label ?? \"Edit this page\",\n };\n}\n\nfunction resolveCodeBlockLintOptions(\n options: OxContentOptions[\"codeBlockLint\"],\n): ResolvedOptions[\"codeBlockLint\"] {\n if (!options) {\n return { enabled: false, requireLanguage: false, trailingSpaces: true, mode: \"warn\" };\n }\n if (options === true) {\n return { enabled: true, requireLanguage: false, trailingSpaces: true, mode: \"warn\" };\n }\n return {\n enabled: true,\n languages: options.languages,\n requireLanguage: options.requireLanguage ?? false,\n trailingSpaces: options.trailingSpaces ?? true,\n mode: options.mode ?? \"warn\",\n };\n}\n\nfunction resolveCodeBlockTypecheckOptions(\n options: OxContentOptions[\"codeBlockTypecheck\"],\n): ResolvedOptions[\"codeBlockTypecheck\"] {\n if (!options) {\n return {\n enabled: false,\n languages: [\"ts\", \"tsx\"],\n requireMeta: true,\n tsgoCommand: \"tsgo\",\n mode: \"warn\",\n };\n }\n if (options === true) {\n return {\n enabled: true,\n languages: [\"ts\", \"tsx\"],\n requireMeta: true,\n tsgoCommand: \"tsgo\",\n mode: \"warn\",\n };\n }\n return {\n enabled: true,\n languages: options.languages ?? [\"ts\", \"tsx\"],\n requireMeta: options.requireMeta ?? true,\n tsgoCommand: options.tsgoCommand ?? \"tsgo\",\n mode: options.mode ?? \"warn\",\n };\n}\n\nfunction resolveDocsTestOptions(\n options: OxContentOptions[\"docsTests\"],\n): ResolvedOptions[\"docsTests\"] {\n if (!options) return { enabled: false, languages: [\"js\", \"jsx\", \"ts\", \"tsx\"], requireMeta: true };\n if (options === true) {\n return { enabled: true, languages: [\"js\", \"jsx\", \"ts\", \"tsx\"], requireMeta: true };\n }\n return {\n enabled: true,\n languages: options.languages ?? [\"js\", \"jsx\", \"ts\", \"tsx\"],\n requireMeta: options.requireMeta ?? true,\n };\n}\n\nfunction resolveCodeAnnotationsOptions(\n options: OxContentOptions[\"codeAnnotations\"],\n): ResolvedOptions[\"codeAnnotations\"] {\n if (!options) {\n return {\n enabled: false,\n notation: \"attribute\",\n metaKey: \"annotate\",\n defaultLineNumbers: false,\n };\n }\n\n if (options === true) {\n return {\n enabled: true,\n notation: \"attribute\",\n metaKey: \"annotate\",\n defaultLineNumbers: false,\n };\n }\n\n return {\n enabled: true,\n notation: options.notation ?? \"attribute\",\n metaKey: options.metaKey ?? \"annotate\",\n defaultLineNumbers: options.defaultLineNumbers ?? false,\n };\n}\n\n/**\n * Generates virtual module content.\n */\nexport function generateVirtualModule(path: string, options: ResolvedOptions): string {\n if (path === \"config\") {\n return `export default ${JSON.stringify(options)};`;\n }\n\n if (path === \"runtime\") {\n const base = normalizeRuntimeBase(options.base);\n return `\n export const base = ${JSON.stringify(base)};\n export const runtimeConfig = { base };\n\n export function isExternalUrl(value) {\n return /^(?:https?:)?\\\\/\\\\//i.test(value) || /^(?:mailto|tel):/i.test(value);\n }\n\n export function withBase(pathname = \"\") {\n const value = String(pathname);\n if (!value || value === \"/\") return base;\n if (value.startsWith(\"#\") || isExternalUrl(value)) return value;\n return base + (value.startsWith(\"/\") ? value.slice(1) : value);\n }\n\n export function withoutBase(pathname = \"\") {\n const value = String(pathname);\n if (base === \"/\" || value.startsWith(\"#\") || isExternalUrl(value)) return value;\n const bareBase = base.slice(0, -1);\n if (value === bareBase) return \"/\";\n if (value.startsWith(base)) return \"/\" + value.slice(base.length);\n return value;\n }\n\n export function useMarkdown() {\n return {\n base,\n withBase,\n withoutBase,\n render: (content) => {\n return content;\n },\n };\n }\n `;\n }\n\n return \"export default {};\";\n}\n\nfunction normalizeRuntimeBase(base: string): string {\n const trimmed = base.trim();\n if (!trimmed || trimmed === \"/\") return \"/\";\n const withLeading = trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n return withLeading.endsWith(\"/\") ? withLeading : `${withLeading}/`;\n}\n\n// Re-export types and utilities\nexport { createMarkdownEnvironment } from \"./environment\";\nexport { transformMarkdown } from \"./transform\";\nexport {\n extractCodeBlocks,\n extractDocsTests,\n lintCodeBlocks,\n typecheckCodeBlocks,\n type CodeBlockDiagnostic,\n type ExtractedCodeBlock,\n type TypecheckCodeBlockOptions,\n} from \"./code-blocks\";\nexport {\n collectDocsTests,\n DocsTestRunError,\n runDocsTests,\n writeDocsTestFiles,\n type CollectedDocsTest,\n type DocsTestFileOptions,\n type DocsTestHarnessOptions,\n type DocsTestRunResult,\n type DocsTestSource,\n type DocsTestWriteResult,\n type RunDocsTestsOptions,\n type WrittenDocsTestFile,\n} from \"./docs-tests\";\nexport { extractDocs, generateMarkdown, writeDocs, resolveDocsOptions } from \"./docs\";\nexport { lintMarkdown, lintMarkdownAsync } from \"./lint\";\nexport { lintMarkdownFile, lintMarkdownFiles, shouldLintMarkdownFile } from \"./lint-files\";\nexport type {\n MarkdownLintDiagnostic,\n MarkdownLintDictionaryOptions,\n MarkdownLintLanguage,\n MarkdownLintOptions,\n MarkdownLintResult,\n MarkdownLintRuleOptions,\n MarkdownLintSeverity,\n MarkdownLintStandardDictionaryOptions,\n} from \"./lint\";\nexport type {\n MarkdownLintFileDiagnostic as MarkdownLintBatchDiagnostic,\n MarkdownLintFileDiagnostic,\n MarkdownLintFileOptions,\n MarkdownLintFileResult,\n MarkdownLintFilesResult,\n MarkdownLintFileOptions as MarkdownLintProjectOptions,\n} from \"./lint-files\";\nexport { buildSsg, resolveSsgOptions, DEFAULT_HTML_TEMPLATE } from \"./ssg\";\nexport { resolveSearchOptions, buildSearchIndex, writeSearchIndex } from \"./search\";\nexport {\n DEFAULT_MARKDOWN_EXTENSIONS,\n normalizeMarkdownExtensions,\n isMarkdownFilePath,\n stripMarkdownExtension,\n} from \"./markdown\";\nexport { defineTheme, defaultTheme, mergeThemes, resolveTheme } from \"./theme\";\nexport {\n fromVitePressConfig,\n generateVitePressMigrationConfig,\n convertVitePressSidebar,\n convertVitePressNav,\n normalizeVitePressFrontmatter,\n} from \"./vitepress\";\nexport type {\n GenerateVitePressMigrationConfigOptions,\n VitePressConfig,\n VitePressThemeConfig,\n VitePressSidebar,\n VitePressSidebarItem,\n VitePressNavItem,\n VitePressSocialLink,\n VitePressFooter,\n VitePressLogo,\n} from \"./vitepress\";\nexport type {\n ThemeConfig,\n ThemeColors,\n ThemeLayout,\n ThemeFonts,\n ThemeEntryPage,\n ThemeHeader,\n ThemeFooter,\n SocialLinks,\n ThemeEmbed,\n ResolvedThemeConfig,\n} from \"./theme\";\nexport * from \"./types\";\n\n// JSX Runtime\nexport { jsx, jsxs, Fragment, renderToString, raw, when, each } from \"./jsx-runtime\";\nexport type { JSXNode, JSXChild, JSXProps, JSXElementType } from \"./jsx-runtime\";\n\n// Page Context\nexport {\n usePageProps,\n useSiteConfig,\n useRenderContext,\n useNav,\n useIsActive,\n setRenderContext,\n clearRenderContext,\n generateFrontmatterTypes,\n inferType,\n} from \"./page-context\";\nexport type {\n BasePageProps,\n PageProps,\n SiteConfig,\n NavGroup,\n NavItem,\n RenderContext,\n FrontmatterSchema,\n} from \"./page-context\";\n\n// Theme Renderer\nexport {\n renderPage,\n renderAllPages,\n generateTypes,\n DefaultTheme,\n createTheme,\n} from \"./theme-renderer\";\nexport type { ThemeComponent, ThemeProps, PageData, ThemeRenderOptions } from \"./theme-renderer\";\n\n// Built-in Plugins (No-JS First)\nexport {\n transformTabs,\n generateTabsCSS,\n transformYouTube,\n extractVideoId,\n transformGitHub,\n fetchRepoData,\n fetchGitHubSource,\n collectGitHubRepos,\n collectGitHubSources,\n prefetchGitHubRepos,\n prefetchGitHubSources,\n parseGitHubPermalink,\n parseGitHubLineRange,\n transformOgp,\n fetchOgpData,\n collectOgpUrls,\n prefetchOgpData,\n transformMermaidStatic,\n mermaidClientScript,\n transformAllPlugins,\n} from \"./plugins\";\nexport type {\n YouTubeOptions,\n GitHubRepoData,\n GitHubSourceData,\n GitHubSourceRef,\n GitHubLineRange,\n GitHubOptions,\n OgpData,\n OgpOptions,\n MermaidOptions,\n TransformAllOptions,\n} from \"./plugins\";\n\n// Island Architecture\nexport { transformIslands, hasIslands, extractIslandInfo, generateHydrationScript } from \"./island\";\nexport type { LoadStrategy, IslandInfo, ParseIslandsResult } from \"./island\";\n\n// OG Image\nexport { resolveOgImageOptions, generateOgImages } from \"./og-image\";\nexport { resolveI18nOptions, createI18nPlugin } from \"./i18n\";\nexport type {\n OgImageOptions as OgImagePluginOptions,\n ResolvedOgImageOptions,\n OgImageTemplateProps,\n OgImageTemplateFn,\n OgImagePageEntry,\n OgImageResult,\n OgBrowserSession,\n} from \"./og-image\";\n"],"mappings":"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"}