@docubook/core 1.8.1 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -90,8 +90,8 @@ const tocs = await docsService.getTocsForSlug("getting-started/introduction");
|
|
|
90
90
|
| `handleCodeExpandableRemark` | Remark plugin that detects `Expandable` meta on code blocks and injects expandable data attributes | transformer function |
|
|
91
91
|
| `handleCodeExpandable` | Rehype plugin that propagates expandable metadata from `<code>` to `<pre>` elements | transformer function |
|
|
92
92
|
| `rehypeMermaid` | Rehype plugin that transforms ` ```mermaid ` fenced code blocks into `<Mermaid chart="...">` elements | transformer function |
|
|
93
|
-
| `serialize` | Re-exported from
|
|
94
|
-
| `MDXRemote` | Re-exported from
|
|
93
|
+
| `serialize` | Re-exported from `@docubook/mdx-remote/serialize` for non-RSC MDX compilation workflows | `MDXRemoteSerializeResult` |
|
|
94
|
+
| `MDXRemote` | Re-exported from `@docubook/mdx-remote` for client-side MDX hydration | React component |
|
|
95
95
|
| `cn` | Merge class names using `clsx` + `tailwind-merge` | `string` |
|
|
96
96
|
| `parseDate` | Parse `dd-MM-yyyy` or ISO 8601 date strings into a Date object | `Date` |
|
|
97
97
|
| `stringToDate` | Convert a string or Date value to a Date object | `Date` |
|
|
@@ -408,7 +408,7 @@ This means app-level users should focus on content and integration. Plugin upgra
|
|
|
408
408
|
|
|
409
409
|
- clsx — class name composition for the `cn()` utility
|
|
410
410
|
- tailwind-merge — intelligent Tailwind class merging for the `cn()` utility
|
|
411
|
-
-
|
|
411
|
+
- @docubook/mdx-remote — MDX runtime/compile engine (`serialize`, `MDXRemote`)
|
|
412
412
|
|
|
413
413
|
The `remark` and `rehype` plugin stack is intentionally owned by this package to avoid dependency drift across apps.
|
|
414
414
|
|
|
@@ -421,11 +421,11 @@ The `remark` and `rehype` plugin stack is intentionally owned by this package to
|
|
|
421
421
|
|
|
422
422
|
## Notes
|
|
423
423
|
|
|
424
|
-
`@docubook/core` already includes and manages the MDX runtime/compile dependencies (including
|
|
424
|
+
`@docubook/core` already includes and manages the MDX runtime/compile dependencies (including `@docubook/mdx-remote`) as part of the package contract.
|
|
425
425
|
|
|
426
426
|
In most integrations, users only need to install `@docubook/core` and use the core APIs.
|
|
427
427
|
|
|
428
|
-
Only
|
|
428
|
+
Only import `@docubook/mdx-remote` directly in your app if your app explicitly needs it in app-level code.
|
|
429
429
|
|
|
430
430
|
For compile pipeline plugins (especially `remark` and `rehype` plugins), rely on this package and avoid re-declaring them at app level unless you have a specific override requirement.
|
|
431
431
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
export { cn, formatDate, formatDate2, parseDate, stringToDate, toIsoDateOnly } from './utils.js';
|
|
3
|
-
import { compileMDX } from '
|
|
3
|
+
import { compileMDX } from '@docubook/mdx-remote/rsc';
|
|
4
4
|
import { Node } from 'unist';
|
|
5
5
|
import { Pluggable } from 'unified';
|
|
6
|
-
export { MDXRemote } from '
|
|
7
|
-
export { serialize } from '
|
|
6
|
+
export { MDXRemote } from '@docubook/mdx-remote';
|
|
7
|
+
export { serialize } from '@docubook/mdx-remote/serialize';
|
|
8
8
|
import 'clsx';
|
|
9
9
|
|
|
10
10
|
type TocItem = {
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
} from "./chunk-HZJLRYAI.js";
|
|
9
9
|
|
|
10
10
|
// src/compile.ts
|
|
11
|
-
import { compileMDX } from "
|
|
12
|
-
import { serialize } from "
|
|
11
|
+
import { compileMDX } from "@docubook/mdx-remote/rsc";
|
|
12
|
+
import { serialize } from "@docubook/mdx-remote/serialize";
|
|
13
13
|
import { visit as visit4 } from "unist-util-visit";
|
|
14
14
|
import remarkGfm from "remark-gfm";
|
|
15
15
|
import rehypePrism from "rehype-prism-plus";
|
|
@@ -201,7 +201,7 @@ var rehypeMermaid = () => (tree) => {
|
|
|
201
201
|
};
|
|
202
202
|
|
|
203
203
|
// src/compile.ts
|
|
204
|
-
import { MDXRemote } from "
|
|
204
|
+
import { MDXRemote } from "@docubook/mdx-remote";
|
|
205
205
|
var preProcess = () => (tree) => {
|
|
206
206
|
visit4(tree, (node) => {
|
|
207
207
|
const element = node;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/compile.ts","../src/plugins/handleCodeTitles.ts","../src/plugins/handleCodeExpandable.ts","../src/plugins/rehypeMermaid.ts","../src/extract.ts","../src/content.ts"],"sourcesContent":["import { compileMDX } from \"next-mdx-remote/rsc\";\nimport { serialize } from \"next-mdx-remote/serialize\";\nimport type { Node } from \"unist\";\nimport { visit } from \"unist-util-visit\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypePrism from \"rehype-prism-plus\";\nimport rehypeAutolinkHeadings from \"rehype-autolink-headings\";\nimport rehypeSlug from \"rehype-slug\";\nimport rehypeCodeTitles from \"rehype-code-titles\";\nimport { handleCodeTitles } from \"./plugins/handleCodeTitles\";\nimport { handleCodeExpandableRemark, handleCodeExpandable } from \"./plugins/handleCodeExpandable\";\nimport { rehypeMermaid } from \"./plugins/rehypeMermaid\";\nimport type { MdxCompileResult } from \"./types\";\nimport type { ElementNode } from \"./utils\";\nimport type { Pluggable } from \"unified\";\n\n// Re-export serialize for non-RSC usage\nexport { serialize };\n\n// Re-export MDXRemote for client-side hydration\nexport { MDXRemote } from \"next-mdx-remote\";\n\ninterface TextNode extends Node {\n type: \"text\";\n value: string;\n}\n\ntype CompileMdxInput = Parameters<typeof compileMDX<Record<string, unknown>>>[0];\ntype CompileMdxOptions = NonNullable<CompileMdxInput[\"options\"]>;\ntype CompilerMdxOptions = NonNullable<CompileMdxOptions[\"mdxOptions\"]>;\n\nexport type ParseMdxOptions = {\n components?: CompileMdxInput[\"components\"];\n rehypePlugins?: CompilerMdxOptions[\"rehypePlugins\"];\n remarkPlugins?: CompilerMdxOptions[\"remarkPlugins\"];\n /**\n * Whether to parse frontmatter during MDX compilation.\n * Set to `false` when frontmatter is already extracted separately\n * (e.g. via gray-matter) to avoid redundant parsing.\n * Defaults to `true`.\n */\n parseFrontmatter?: boolean;\n};\n\nexport const preProcess = () => (tree: Node) => {\n visit(tree, (node: Node) => {\n const element = node as ElementNode;\n if (element?.type === \"element\" && element?.tagName === \"pre\" && element.children) {\n const [codeEl] = element.children as ElementNode[];\n if (codeEl.tagName !== \"code\" || !codeEl.children?.[0]) return;\n\n const className = codeEl.properties?.className;\n const classList = Array.isArray(className)\n ? className\n : typeof className === \"string\"\n ? className.split(\" \").filter(Boolean)\n : [];\n const languageClass = classList.find((item: string) => item.startsWith(\"language-\"));\n if (languageClass) {\n element.language = languageClass.replace(\"language-\", \"\").split(\":\")[0];\n }\n\n const textNode = codeEl.children[0] as TextNode;\n if (textNode.type === \"text\" && textNode.value) {\n element.raw = textNode.value;\n }\n }\n });\n\n return tree;\n};\n\nexport const postProcess = () => (tree: Node) => {\n visit(tree, \"element\", (node: Node) => {\n const element = node as ElementNode;\n if (element?.type === \"element\" && element?.tagName === \"pre\") {\n if (element.properties && element.raw) {\n element.properties.raw = element.raw;\n }\n if (element.properties && element.language && !element.properties[\"data-language\"]) {\n element.properties[\"data-language\"] = element.language;\n }\n if (element.properties && element.codeTitle && !element.properties[\"data-title\"]) {\n element.properties[\"data-title\"] = element.codeTitle;\n }\n }\n });\n\n return tree;\n};\n\nexport function createDefaultRehypePlugins(): Pluggable[] {\n return [\n preProcess,\n rehypeMermaid, // Transform ```mermaid before code transforms\n rehypeCodeTitles,\n handleCodeTitles,\n handleCodeExpandable, // Copy expandable metadata from <code> to <pre> before prism transforms nodes.\n rehypePrism,\n handleCodeExpandable, // Re-apply expandable attrs after prism tokenization.\n rehypeSlug,\n rehypeAutolinkHeadings,\n postProcess,\n ];\n}\n\nexport function createDefaultRemarkPlugins(): Pluggable[] {\n return [remarkGfm, handleCodeExpandableRemark];\n}\n\nexport async function parseMdx<Frontmatter>(\n rawMdx: string,\n options: ParseMdxOptions = {}\n): Promise<MdxCompileResult<Frontmatter>> {\n const rehypePlugins =\n options.rehypePlugins ?? (createDefaultRehypePlugins() as CompilerMdxOptions[\"rehypePlugins\"]);\n const remarkPlugins =\n options.remarkPlugins ?? (createDefaultRemarkPlugins() as CompilerMdxOptions[\"remarkPlugins\"]);\n\n return await compileMDX<Frontmatter>({\n source: rawMdx,\n options: {\n parseFrontmatter: options.parseFrontmatter ?? true,\n mdxOptions: {\n rehypePlugins,\n remarkPlugins,\n },\n },\n components: options.components,\n });\n}\n","import type { Node, Parent } from \"unist\"\nimport { visit } from \"unist-util-visit\"\nimport type { ElementNode } from \"../utils\"\n\ninterface TextNode extends Node {\n type: \"text\"\n value: string\n}\n\nexport const handleCodeTitles = () => (tree: Node) => {\n const toRemove: { parent: Parent; index: number }[] = []\n\n visit(tree, \"element\", (node: ElementNode, index: number | null, parent: Parent | null) => {\n if (!parent || index === null || node.tagName !== \"div\") {\n return\n }\n\n const isTitleDiv = node.properties?.className?.includes(\"rehype-code-title\")\n if (!isTitleDiv) {\n return\n }\n\n let nextElement: ElementNode | null = null\n for (let i = index + 1; i < parent.children.length; i++) {\n const sibling = parent.children[i]\n if (sibling.type === \"element\") {\n nextElement = sibling as ElementNode\n break\n }\n }\n\n if (nextElement?.tagName === \"pre\") {\n const titleNode = node.children?.[0] as TextNode\n if (titleNode?.type === \"text\") {\n if (!nextElement.properties) {\n nextElement.properties = {}\n }\n nextElement.properties[\"data-title\"] = titleNode.value\n nextElement.codeTitle = titleNode.value\n toRemove.push({ parent, index })\n }\n }\n })\n\n // Remove title divs in reverse order to preserve indices\n for (let i = toRemove.length - 1; i >= 0; i--) {\n const { parent, index } = toRemove[i]\n parent.children.splice(index, 1)\n }\n}\n","import type { Node } from \"unist\";\nimport { visit } from \"unist-util-visit\";\nimport type { ElementNode } from \"../utils\";\n\n/**\n * Escape metadata values that are interpolated into MDX-compiled JavaScript.\n *\n * References:\n * - HTML spec (script data state): escape `</` as `\\u003C/` to prevent premature\n * `</script>` closing when the compiled JS is embedded as JSON in a <script> tag.\n * - Bun.escapeHTML(): escapes `< > \" ' &` for HTML context; for JS/JSON context\n * we use `\\uXXXX` JSON Unicode escapes instead so the value survives round-trip\n * through JSON.parse on the client side.\n * - React: JSX auto-escapes attribute values via `{expression}`, so values set\n * as HAST properties (data-language, data-title) are HTML-safe at render time.\n */\nfunction escapeMeta(s: string): string {\n let out = \"\";\n for (let i = 0; i < s.length; i++) {\n const ch = s[i];\n\n // HTML spec: prevent </script> in script/JSON context\n if (ch === \"<\" && s[i + 1] === \"/\") {\n out += \"\\\\u003C/\";\n i++;\n continue;\n }\n\n // JS string: escape template literal & string special chars\n if (ch === \"`\" || ch === \"$\" || ch === \"{\" || ch === \"}\" || ch === \"\\\"\" || ch === \"\\\\\") {\n out += `\\\\${ch}`;\n continue;\n }\n\n out += ch;\n }\n return out;\n}\n\ninterface CodeNode extends Node {\n type: \"code\";\n lang?: string;\n meta?: string;\n value: string;\n data?: {\n meta?: string;\n hProperties?: Record<string, unknown>;\n };\n}\n\nfunction countCodeLines(raw: string): number {\n let normalized = raw.replace(/\\r\\n/g, \"\\n\");\n if (normalized.startsWith(\"\\n\")) normalized = normalized.slice(1);\n if (normalized.endsWith(\"\\n\")) normalized = normalized.slice(0, -1);\n\n if (normalized.length === 0) return 0;\n return normalized.split(\"\\n\").length;\n}\n\nexport const handleCodeExpandableRemark = () => (tree: Node) => {\n visit(tree, \"code\", (node: CodeNode) => {\n if (!node.meta) return;\n\n const isExpandable = node.meta.includes(\"Expandable\");\n const [languagePart, titlePart] = (node.lang ?? \"\").split(\":\");\n const normalizedLanguage = languagePart?.trim();\n const normalizedTitle = titlePart?.trim();\n\n if (!isExpandable) return;\n\n const lineCount = countCodeLines(node.value);\n\n if (!node.data) {\n node.data = {};\n }\n if (!node.data.hProperties) {\n node.data.hProperties = {};\n }\n\n node.data.hProperties[\"data-expandable\"] = \"true\";\n node.data.hProperties[\"data-expandable-lines\"] = lineCount.toString();\n\n if (normalizedLanguage) {\n node.data.hProperties[\"data-language\"] = normalizedLanguage;\n }\n if (normalizedTitle) {\n node.data.hProperties[\"data-title\"] = normalizedTitle;\n }\n\n const currentClassName = node.data.hProperties.className;\n const classList = Array.isArray(currentClassName)\n ? currentClassName\n : typeof currentClassName === \"string\"\n ? currentClassName.split(\" \").filter(Boolean)\n : [];\n\n if (!classList.includes(\"mdx-expandable-meta\")) {\n classList.push(\"mdx-expandable-meta\");\n }\n\n node.data.hProperties.className = classList;\n\n if (normalizedLanguage && !node.meta.includes(\"dbLang(\")) {\n node.meta = `${node.meta} dbLang(${escapeMeta(normalizedLanguage)})`.trim();\n }\n if (normalizedTitle && !node.meta.includes(\"dbTitle(\")) {\n node.meta = `${node.meta} dbTitle(${escapeMeta(normalizedTitle)})`.trim();\n }\n });\n};\n\nexport const handleCodeExpandable = () => (tree: Node) => {\n visit(tree, \"element\", (node: ElementNode) => {\n if (node.tagName !== \"pre\") return;\n\n const codeElement = node.children?.find((child) => {\n const element = child as ElementNode;\n return element.type === \"element\" && element.tagName === \"code\";\n }) as ElementNode | undefined;\n\n const codeClassName = codeElement?.properties?.className;\n const codeClassList = Array.isArray(codeClassName)\n ? codeClassName\n : typeof codeClassName === \"string\"\n ? codeClassName.split(\" \").filter(Boolean)\n : [];\n\n const codeMeta =\n codeElement?.data &&\n typeof codeElement.data === \"object\" &&\n typeof codeElement.data[\"meta\"] === \"string\"\n ? (codeElement.data[\"meta\"] as string)\n : undefined;\n\n const languageFromMeta = codeMeta?.match(/dbLang\\(([^)]+)\\)/)?.[1];\n const titleFromMeta = codeMeta?.match(/dbTitle\\(([^)]+)\\)/)?.[1];\n\n const languageFromProps =\n typeof codeElement?.properties?.[\"data-language\"] === \"string\"\n ? (codeElement.properties[\"data-language\"] as string)\n : undefined;\n const titleFromProps =\n typeof codeElement?.properties?.[\"data-title\"] === \"string\"\n ? (codeElement.properties[\"data-title\"] as string)\n : undefined;\n\n const languageFromCodeClass = codeClassList\n .find((item) => item.startsWith(\"language-\"))\n ?.replace(\"language-\", \"\");\n\n const existingPreLanguage =\n typeof node.properties?.[\"data-language\"] === \"string\"\n ? (node.properties[\"data-language\"] as string)\n : undefined;\n const existingPreTitle =\n typeof node.properties?.[\"data-title\"] === \"string\"\n ? (node.properties[\"data-title\"] as string)\n : undefined;\n\n const isExpandable =\n codeElement?.properties?.[\"data-expandable\"] === \"true\" ||\n codeClassList.includes(\"mdx-expandable-meta\") ||\n codeMeta?.includes(\"Expandable\") === true;\n\n const expandableLines = codeElement?.properties?.[\"data-expandable-lines\"];\n if (!isExpandable) return;\n\n if (!node.properties) {\n node.properties = {};\n }\n\n node.properties[\"data-expandable\"] = \"true\";\n if (typeof expandableLines === \"string\" || typeof expandableLines === \"number\") {\n node.properties[\"data-expandable-lines\"] = expandableLines.toString();\n } else if (node.raw) {\n node.properties[\"data-expandable-lines\"] = countCodeLines(node.raw).toString();\n }\n\n const resolvedLanguage =\n languageFromProps ||\n languageFromMeta ||\n languageFromCodeClass ||\n existingPreLanguage ||\n node.language;\n const resolvedTitle = titleFromProps || titleFromMeta || existingPreTitle || node.codeTitle;\n\n if (resolvedLanguage) {\n node.properties[\"data-language\"] = resolvedLanguage;\n }\n if (resolvedTitle) {\n node.properties[\"data-title\"] = resolvedTitle;\n }\n\n const className = node.properties.className;\n if (!className) {\n node.properties.className = [];\n }\n\n if (Array.isArray(node.properties.className)) {\n if (!node.properties.className.includes(\"mdx-expandable-code\")) {\n node.properties.className.push(\"mdx-expandable-code\");\n }\n } else if (typeof className === \"string\") {\n const hasMarker = className.split(\" \").includes(\"mdx-expandable-code\");\n if (!hasMarker) {\n node.properties.className = `${className} mdx-expandable-code`.trim().split(\" \");\n }\n } else {\n node.properties.className = [\"mdx-expandable-code\"];\n }\n\n if (codeElement?.properties) {\n const cleanedCodeClassList = codeClassList.filter((item) => item !== \"mdx-expandable-meta\");\n codeElement.properties.className = cleanedCodeClassList;\n }\n });\n};\n","import type { Node, Parent } from \"unist\";\nimport { visit } from \"unist-util-visit\";\nimport type { ElementNode } from \"../utils\";\n\ninterface TextNode extends Node {\n type: \"text\";\n value: string;\n}\n\n/**\n * Rehype plugin that transforms `<pre><code class=\"language-mermaid\">` fenced\n * blocks into `<Mermaid chart=\"...\">` elements.\n *\n * This allows Mermaid diagram definitions to be authored via standard fenced\n * code blocks (````mermaid) which avoids JSX parsing collisions with\n * Mermaid's `{...}` (decision nodes) and `[...]` (label nodes) syntax.\n */\nexport const rehypeMermaid = () => (tree: Node) => {\n visit(tree, \"element\", (node: ElementNode, index: number | null, parent: Parent | null) => {\n if (!parent || index === null || node.tagName !== \"pre\") return;\n\n const codeEl = node.children?.find(\n (child) =>\n (child as ElementNode).type === \"element\" && (child as ElementNode).tagName === \"code\"\n ) as ElementNode | undefined;\n\n if (!codeEl) return;\n\n const classList = Array.isArray(codeEl.properties?.className)\n ? (codeEl.properties.className as string[])\n : typeof codeEl.properties?.className === \"string\"\n ? (codeEl.properties.className as string).split(\" \").filter(Boolean)\n : [];\n\n if (!classList.includes(\"language-mermaid\")) return;\n\n const textNode = codeEl.children?.find((child) => (child as TextNode).type === \"text\") as\n | TextNode\n | undefined;\n\n const chart = textNode?.value ?? \"\";\n\n parent.children[index] = {\n type: \"element\",\n tagName: \"Mermaid\",\n properties: { chart },\n children: [],\n } as unknown as ElementNode;\n });\n};\n","import matter from \"@11ty/gray-matter\";\nimport type { TocItem } from \"./types\";\n\nconst FENCE_MARKER_REGEX = /^(````|```)(?!`)/;\nconst HEADING_REGEX = /^(#{2,4})\\s+(.+)$/;\nconst RELEASE_VERSION_ATTR_REGEX = /\\bversion\\s*=\\s*\"([^\"]+)\"/;\n\nexport function sluggify(text: string): string {\n const normalized = text.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\"); // Remove accents\n const slug = normalized.toLowerCase().replace(/\\s+/g, \"-\");\n return slug.replace(/[^a-z0-9-]/g, \"\");\n}\n\nfunction parseReleaseVersionFromLine(line: string): string | null {\n const releaseStart = line.indexOf(\"<Release\");\n if (releaseStart === -1) {\n return null;\n }\n\n // Parse only the first tag fragment on the line to avoid broad regex scans.\n const fragment = line.slice(releaseStart, releaseStart + 512);\n const closingIndex = fragment.indexOf(\">\");\n if (closingIndex === -1) {\n return null;\n }\n\n const tag = fragment.slice(0, closingIndex + 1);\n if (!/^<Release\\b/.test(tag)) {\n return null;\n }\n\n const attrMatch = RELEASE_VERSION_ATTR_REGEX.exec(tag);\n const version = attrMatch?.[1] ?? \"\";\n return version.trim() || null;\n}\n\nexport function extractTocsFromRawMdx(rawMdx: string): TocItem[] {\n const extractedHeadings: TocItem[] = [];\n\n const lines = rawMdx.split(/\\r?\\n/);\n let inFence = false;\n let fenceLength = 0;\n\n for (const line of lines) {\n const trimmed = line.trimStart();\n\n const fenceMatch = FENCE_MARKER_REGEX.exec(trimmed);\n if (fenceMatch) {\n const marker = fenceMatch[1];\n\n if (!inFence) {\n inFence = true;\n fenceLength = marker.length;\n } else if (marker.length === fenceLength) {\n inFence = false;\n }\n\n continue;\n }\n\n if (inFence) {\n continue;\n }\n\n const headingMatch = HEADING_REGEX.exec(trimmed);\n if (headingMatch) {\n const headingLevel = headingMatch[1].length;\n const headingText = headingMatch[2].trim().replace(/\\s+#+\\s*$/, \"\");\n extractedHeadings.push({\n level: headingLevel,\n text: headingText,\n href: `#${sluggify(headingText)}`,\n });\n continue;\n }\n\n const version = parseReleaseVersionFromLine(line);\n if (version) {\n extractedHeadings.push({\n level: 2,\n text: `v${version}`,\n href: `#${version}`,\n });\n }\n }\n\n return extractedHeadings;\n}\n\nexport function extractFrontmatter<Frontmatter>(content: string): Frontmatter {\n try {\n return matter(content).data as Frontmatter;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to extract frontmatter: ${reason}`);\n }\n}\n\n/**\n * Extract frontmatter and return both the parsed data and the content\n * with the frontmatter block stripped. Avoids a second parse by compileMDX.\n */\nexport function extractFrontmatterWithContent<Frontmatter>(content: string): {\n frontmatter: Frontmatter;\n strippedContent: string;\n} {\n try {\n const { data, content: strippedContent } = matter(content);\n return { frontmatter: data as Frontmatter, strippedContent };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to extract frontmatter: ${reason}`);\n }\n}\n","import path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport { extractFrontmatterWithContent, extractTocsFromRawMdx } from \"./extract\";\nimport { parseMdx, type ParseMdxOptions } from \"./compile\";\nimport type { MdxCompileResult, TocItem } from \"./types\";\n\ntype CacheFn = <T extends (...args: any[]) => any>(fn: T) => T;\n\nexport type ReadMdxFileResult = {\n content: string;\n /** Relative path used for UI links (e.g. \"docs/getting-started/index.mdx\"). */\n filePath: string;\n /** Absolute path on disk — available when file was read by readMdxFileBySlug. */\n absoluteFilePath?: string;\n};\n\nexport type ParsedMdxFile<Frontmatter, T extends TocItem = TocItem> = {\n /** Raw content with frontmatter block stripped — ready to pass to compileMDX. */\n content: string;\n filePath: string;\n frontmatter: Frontmatter;\n tocs: T[];\n};\n\nexport type CompiledMdxFile<\n Frontmatter,\n T extends TocItem = TocItem,\n> = MdxCompileResult<Frontmatter> & {\n filePath: string;\n tocs: T[];\n};\n\ntype ReadMdxBySlugOptions = {\n rootDir?: string;\n docsDir?: string;\n};\n\nexport async function readMdxFileBySlug(\n slug: string,\n options: ReadMdxBySlugOptions = {}\n): Promise<ReadMdxFileResult> {\n if (!slug || slug.trim() === \"\") {\n // Handle root slug as \"index\"\n slug = \"index\";\n }\n const docsDir = options.docsDir ?? \"docs\";\n // Keep file-system path operations ignored by Turbopack tracing.\n // The runtime path is constrained to docsDir and slug candidates below.\n const docsRoot = options.rootDir\n ? path.join(/*turbopackIgnore: true*/ options.rootDir, docsDir)\n : path.join(/*turbopackIgnore: true*/ process.cwd(), docsDir);\n\n // Resolve once for path-traversal guard — all candidate paths must stay\n // escaping the docs directory, especially important with dynamicParams=true.\n const resolvedRoot = path.resolve(/*turbopackIgnore: true*/ docsRoot);\n\n const paths = [\n path.join(/*turbopackIgnore: true*/ docsRoot, `${slug}.mdx`),\n path.join(/*turbopackIgnore: true*/ docsRoot, slug, \"index.mdx\"),\n ];\n // console.log(`Attempting to read slug: \"${slug}\", paths:`, paths); // Debug log\n\n for (const p of paths) {\n // Guard: reject any path that escapes the docs root.\n const resolvedP = path.resolve(/*turbopackIgnore: true*/ p);\n if (!resolvedP.startsWith(resolvedRoot + path.sep) && resolvedP !== resolvedRoot) {\n continue;\n }\n\n try {\n const content = await fs.readFile(/*turbopackIgnore: true*/ p, \"utf-8\");\n return {\n content,\n filePath: `${docsDir}/${path.relative(/*turbopackIgnore: true*/ docsRoot, p)}`,\n absoluteFilePath: p,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n throw error;\n }\n }\n\n throw new Error(\"Could not find mdx file for the requested slug.\");\n}\n\ntype ParseMdxFileOptions<T extends TocItem> = {\n tocsExtractor?: (rawMdx: string) => T[];\n};\n\nexport function parseMdxFile<Frontmatter, T extends TocItem = TocItem>(\n raw: ReadMdxFileResult,\n options: ParseMdxFileOptions<T> = {}\n): ParsedMdxFile<Frontmatter, T> {\n const tocsExtractor = options.tocsExtractor ?? ((mdx) => extractTocsFromRawMdx(mdx) as T[]);\n // Extract frontmatter and stripped content in one gray-matter call.\n // strippedContent is passed to compileMDX so it doesn't need to re-parse frontmatter.\n const { frontmatter, strippedContent } = extractFrontmatterWithContent<Frontmatter>(raw.content);\n\n return {\n content: strippedContent,\n filePath: raw.filePath,\n frontmatter,\n tocs: tocsExtractor(raw.content),\n };\n}\n\nexport async function compileParsedMdxFile<Frontmatter, T extends TocItem = TocItem>(\n parsed: ParsedMdxFile<Frontmatter, T>,\n options: ParseMdxOptions = {}\n): Promise<CompiledMdxFile<Frontmatter, T>> {\n // Content in parsed is already stripped of frontmatter by parseMdxFile.\n // Set parseFrontmatter:false — no re-parse needed, avoids double work.\n const compiled = await parseMdx<Frontmatter>(parsed.content, {\n ...options,\n parseFrontmatter: false,\n });\n\n return {\n ...compiled,\n frontmatter: parsed.frontmatter,\n filePath: parsed.filePath,\n tocs: parsed.tocs,\n };\n}\n\nexport type CreateMdxContentServiceOptions<Frontmatter, T extends TocItem = TocItem> = {\n parseOptions?: ParseMdxOptions;\n readOptions?: ReadMdxBySlugOptions;\n tocsExtractor?: (rawMdx: string) => T[];\n cacheFn?: CacheFn;\n /**\n * Optional hook to enrich or transform frontmatter after parsing.\n * Called with the parsed frontmatter and the absolute file path.\n * Runs at build time during static generation — ideal for injecting\n * fallback values (e.g. git last-modified date when `date` is absent).\n */\n frontmatterEnricher?: (\n frontmatter: Frontmatter,\n absoluteFilePath: string\n ) => Frontmatter | Promise<Frontmatter>;\n};\n\nexport function createMdxContentService<Frontmatter, T extends TocItem = TocItem>(\n options: CreateMdxContentServiceOptions<Frontmatter, T> = {}\n) {\n const identityCache: CacheFn = (fn) => fn;\n const cacheFn = options.cacheFn ?? identityCache;\n\n const getParsedForSlug = cacheFn(async (slug: string): Promise<ParsedMdxFile<Frontmatter, T>> => {\n const raw = await readMdxFileBySlug(slug, options.readOptions);\n const parsed = parseMdxFile<Frontmatter, T>(raw, { tocsExtractor: options.tocsExtractor });\n if (options.frontmatterEnricher && raw.absoluteFilePath) {\n parsed.frontmatter = await options.frontmatterEnricher(\n parsed.frontmatter,\n raw.absoluteFilePath\n );\n }\n return parsed;\n });\n\n const getCompiledForSlug = cacheFn(\n async (slug: string): Promise<CompiledMdxFile<Frontmatter, T>> => {\n const parsed = await getParsedForSlug(slug);\n return compileParsedMdxFile<Frontmatter, T>(parsed, options.parseOptions);\n }\n );\n\n async function getFrontmatterForSlug(slug: string): Promise<Frontmatter> {\n const parsed = await getParsedForSlug(slug);\n return parsed.frontmatter;\n }\n\n async function getTocsForSlug(slug: string): Promise<T[]> {\n const parsed = await getParsedForSlug(slug);\n return parsed.tocs;\n }\n\n return {\n getParsedForSlug,\n getCompiledForSlug,\n getFrontmatterForSlug,\n getTocsForSlug,\n };\n}\n"],"mappings":"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","names":["visit","visit","visit","visit"]}
|
|
1
|
+
{"version":3,"sources":["../src/compile.ts","../src/plugins/handleCodeTitles.ts","../src/plugins/handleCodeExpandable.ts","../src/plugins/rehypeMermaid.ts","../src/extract.ts","../src/content.ts"],"sourcesContent":["import { compileMDX } from \"@docubook/mdx-remote/rsc\";\nimport { serialize } from \"@docubook/mdx-remote/serialize\";\nimport type { Node } from \"unist\";\nimport { visit } from \"unist-util-visit\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypePrism from \"rehype-prism-plus\";\nimport rehypeAutolinkHeadings from \"rehype-autolink-headings\";\nimport rehypeSlug from \"rehype-slug\";\nimport rehypeCodeTitles from \"rehype-code-titles\";\nimport { handleCodeTitles } from \"./plugins/handleCodeTitles\";\nimport { handleCodeExpandableRemark, handleCodeExpandable } from \"./plugins/handleCodeExpandable\";\nimport { rehypeMermaid } from \"./plugins/rehypeMermaid\";\nimport type { MdxCompileResult } from \"./types\";\nimport type { ElementNode } from \"./utils\";\nimport type { Pluggable } from \"unified\";\n\n// Re-export serialize for non-RSC usage\nexport { serialize };\n\n// Re-export MDXRemote for client-side hydration\nexport { MDXRemote } from \"@docubook/mdx-remote\";\n\ninterface TextNode extends Node {\n type: \"text\";\n value: string;\n}\n\ntype CompileMdxInput = Parameters<typeof compileMDX<Record<string, unknown>>>[0];\ntype CompileMdxOptions = NonNullable<CompileMdxInput[\"options\"]>;\ntype CompilerMdxOptions = NonNullable<CompileMdxOptions[\"mdxOptions\"]>;\n\nexport type ParseMdxOptions = {\n components?: CompileMdxInput[\"components\"];\n rehypePlugins?: CompilerMdxOptions[\"rehypePlugins\"];\n remarkPlugins?: CompilerMdxOptions[\"remarkPlugins\"];\n /**\n * Whether to parse frontmatter during MDX compilation.\n * Set to `false` when frontmatter is already extracted separately\n * (e.g. via gray-matter) to avoid redundant parsing.\n * Defaults to `true`.\n */\n parseFrontmatter?: boolean;\n};\n\nexport const preProcess = () => (tree: Node) => {\n visit(tree, (node: Node) => {\n const element = node as ElementNode;\n if (element?.type === \"element\" && element?.tagName === \"pre\" && element.children) {\n const [codeEl] = element.children as ElementNode[];\n if (codeEl.tagName !== \"code\" || !codeEl.children?.[0]) return;\n\n const className = codeEl.properties?.className;\n const classList = Array.isArray(className)\n ? className\n : typeof className === \"string\"\n ? className.split(\" \").filter(Boolean)\n : [];\n const languageClass = classList.find((item: string) => item.startsWith(\"language-\"));\n if (languageClass) {\n element.language = languageClass.replace(\"language-\", \"\").split(\":\")[0];\n }\n\n const textNode = codeEl.children[0] as TextNode;\n if (textNode.type === \"text\" && textNode.value) {\n element.raw = textNode.value;\n }\n }\n });\n\n return tree;\n};\n\nexport const postProcess = () => (tree: Node) => {\n visit(tree, \"element\", (node: Node) => {\n const element = node as ElementNode;\n if (element?.type === \"element\" && element?.tagName === \"pre\") {\n if (element.properties && element.raw) {\n element.properties.raw = element.raw;\n }\n if (element.properties && element.language && !element.properties[\"data-language\"]) {\n element.properties[\"data-language\"] = element.language;\n }\n if (element.properties && element.codeTitle && !element.properties[\"data-title\"]) {\n element.properties[\"data-title\"] = element.codeTitle;\n }\n }\n });\n\n return tree;\n};\n\nexport function createDefaultRehypePlugins(): Pluggable[] {\n return [\n preProcess,\n rehypeMermaid, // Transform ```mermaid before code transforms\n rehypeCodeTitles,\n handleCodeTitles,\n handleCodeExpandable, // Copy expandable metadata from <code> to <pre> before prism transforms nodes.\n rehypePrism,\n handleCodeExpandable, // Re-apply expandable attrs after prism tokenization.\n rehypeSlug,\n rehypeAutolinkHeadings,\n postProcess,\n ];\n}\n\nexport function createDefaultRemarkPlugins(): Pluggable[] {\n return [remarkGfm, handleCodeExpandableRemark];\n}\n\nexport async function parseMdx<Frontmatter>(\n rawMdx: string,\n options: ParseMdxOptions = {}\n): Promise<MdxCompileResult<Frontmatter>> {\n const rehypePlugins =\n options.rehypePlugins ?? (createDefaultRehypePlugins() as CompilerMdxOptions[\"rehypePlugins\"]);\n const remarkPlugins =\n options.remarkPlugins ?? (createDefaultRemarkPlugins() as CompilerMdxOptions[\"remarkPlugins\"]);\n\n return await compileMDX<Frontmatter>({\n source: rawMdx,\n options: {\n parseFrontmatter: options.parseFrontmatter ?? true,\n mdxOptions: {\n rehypePlugins,\n remarkPlugins,\n },\n },\n components: options.components,\n });\n}\n","import type { Node, Parent } from \"unist\"\nimport { visit } from \"unist-util-visit\"\nimport type { ElementNode } from \"../utils\"\n\ninterface TextNode extends Node {\n type: \"text\"\n value: string\n}\n\nexport const handleCodeTitles = () => (tree: Node) => {\n const toRemove: { parent: Parent; index: number }[] = []\n\n visit(tree, \"element\", (node: ElementNode, index: number | null, parent: Parent | null) => {\n if (!parent || index === null || node.tagName !== \"div\") {\n return\n }\n\n const isTitleDiv = node.properties?.className?.includes(\"rehype-code-title\")\n if (!isTitleDiv) {\n return\n }\n\n let nextElement: ElementNode | null = null\n for (let i = index + 1; i < parent.children.length; i++) {\n const sibling = parent.children[i]\n if (sibling.type === \"element\") {\n nextElement = sibling as ElementNode\n break\n }\n }\n\n if (nextElement?.tagName === \"pre\") {\n const titleNode = node.children?.[0] as TextNode\n if (titleNode?.type === \"text\") {\n if (!nextElement.properties) {\n nextElement.properties = {}\n }\n nextElement.properties[\"data-title\"] = titleNode.value\n nextElement.codeTitle = titleNode.value\n toRemove.push({ parent, index })\n }\n }\n })\n\n // Remove title divs in reverse order to preserve indices\n for (let i = toRemove.length - 1; i >= 0; i--) {\n const { parent, index } = toRemove[i]\n parent.children.splice(index, 1)\n }\n}\n","import type { Node } from \"unist\";\nimport { visit } from \"unist-util-visit\";\nimport type { ElementNode } from \"../utils\";\n\n/**\n * Escape metadata values that are interpolated into MDX-compiled JavaScript.\n *\n * References:\n * - HTML spec (script data state): escape `</` as `\\u003C/` to prevent premature\n * `</script>` closing when the compiled JS is embedded as JSON in a <script> tag.\n * - Bun.escapeHTML(): escapes `< > \" ' &` for HTML context; for JS/JSON context\n * we use `\\uXXXX` JSON Unicode escapes instead so the value survives round-trip\n * through JSON.parse on the client side.\n * - React: JSX auto-escapes attribute values via `{expression}`, so values set\n * as HAST properties (data-language, data-title) are HTML-safe at render time.\n */\nfunction escapeMeta(s: string): string {\n let out = \"\";\n for (let i = 0; i < s.length; i++) {\n const ch = s[i];\n\n // HTML spec: prevent </script> in script/JSON context\n if (ch === \"<\" && s[i + 1] === \"/\") {\n out += \"\\\\u003C/\";\n i++;\n continue;\n }\n\n // JS string: escape template literal & string special chars\n if (ch === \"`\" || ch === \"$\" || ch === \"{\" || ch === \"}\" || ch === \"\\\"\" || ch === \"\\\\\") {\n out += `\\\\${ch}`;\n continue;\n }\n\n out += ch;\n }\n return out;\n}\n\ninterface CodeNode extends Node {\n type: \"code\";\n lang?: string;\n meta?: string;\n value: string;\n data?: {\n meta?: string;\n hProperties?: Record<string, unknown>;\n };\n}\n\nfunction countCodeLines(raw: string): number {\n let normalized = raw.replace(/\\r\\n/g, \"\\n\");\n if (normalized.startsWith(\"\\n\")) normalized = normalized.slice(1);\n if (normalized.endsWith(\"\\n\")) normalized = normalized.slice(0, -1);\n\n if (normalized.length === 0) return 0;\n return normalized.split(\"\\n\").length;\n}\n\nexport const handleCodeExpandableRemark = () => (tree: Node) => {\n visit(tree, \"code\", (node: CodeNode) => {\n if (!node.meta) return;\n\n const isExpandable = node.meta.includes(\"Expandable\");\n const [languagePart, titlePart] = (node.lang ?? \"\").split(\":\");\n const normalizedLanguage = languagePart?.trim();\n const normalizedTitle = titlePart?.trim();\n\n if (!isExpandable) return;\n\n const lineCount = countCodeLines(node.value);\n\n if (!node.data) {\n node.data = {};\n }\n if (!node.data.hProperties) {\n node.data.hProperties = {};\n }\n\n node.data.hProperties[\"data-expandable\"] = \"true\";\n node.data.hProperties[\"data-expandable-lines\"] = lineCount.toString();\n\n if (normalizedLanguage) {\n node.data.hProperties[\"data-language\"] = normalizedLanguage;\n }\n if (normalizedTitle) {\n node.data.hProperties[\"data-title\"] = normalizedTitle;\n }\n\n const currentClassName = node.data.hProperties.className;\n const classList = Array.isArray(currentClassName)\n ? currentClassName\n : typeof currentClassName === \"string\"\n ? currentClassName.split(\" \").filter(Boolean)\n : [];\n\n if (!classList.includes(\"mdx-expandable-meta\")) {\n classList.push(\"mdx-expandable-meta\");\n }\n\n node.data.hProperties.className = classList;\n\n if (normalizedLanguage && !node.meta.includes(\"dbLang(\")) {\n node.meta = `${node.meta} dbLang(${escapeMeta(normalizedLanguage)})`.trim();\n }\n if (normalizedTitle && !node.meta.includes(\"dbTitle(\")) {\n node.meta = `${node.meta} dbTitle(${escapeMeta(normalizedTitle)})`.trim();\n }\n });\n};\n\nexport const handleCodeExpandable = () => (tree: Node) => {\n visit(tree, \"element\", (node: ElementNode) => {\n if (node.tagName !== \"pre\") return;\n\n const codeElement = node.children?.find((child) => {\n const element = child as ElementNode;\n return element.type === \"element\" && element.tagName === \"code\";\n }) as ElementNode | undefined;\n\n const codeClassName = codeElement?.properties?.className;\n const codeClassList = Array.isArray(codeClassName)\n ? codeClassName\n : typeof codeClassName === \"string\"\n ? codeClassName.split(\" \").filter(Boolean)\n : [];\n\n const codeMeta =\n codeElement?.data &&\n typeof codeElement.data === \"object\" &&\n typeof codeElement.data[\"meta\"] === \"string\"\n ? (codeElement.data[\"meta\"] as string)\n : undefined;\n\n const languageFromMeta = codeMeta?.match(/dbLang\\(([^)]+)\\)/)?.[1];\n const titleFromMeta = codeMeta?.match(/dbTitle\\(([^)]+)\\)/)?.[1];\n\n const languageFromProps =\n typeof codeElement?.properties?.[\"data-language\"] === \"string\"\n ? (codeElement.properties[\"data-language\"] as string)\n : undefined;\n const titleFromProps =\n typeof codeElement?.properties?.[\"data-title\"] === \"string\"\n ? (codeElement.properties[\"data-title\"] as string)\n : undefined;\n\n const languageFromCodeClass = codeClassList\n .find((item) => item.startsWith(\"language-\"))\n ?.replace(\"language-\", \"\");\n\n const existingPreLanguage =\n typeof node.properties?.[\"data-language\"] === \"string\"\n ? (node.properties[\"data-language\"] as string)\n : undefined;\n const existingPreTitle =\n typeof node.properties?.[\"data-title\"] === \"string\"\n ? (node.properties[\"data-title\"] as string)\n : undefined;\n\n const isExpandable =\n codeElement?.properties?.[\"data-expandable\"] === \"true\" ||\n codeClassList.includes(\"mdx-expandable-meta\") ||\n codeMeta?.includes(\"Expandable\") === true;\n\n const expandableLines = codeElement?.properties?.[\"data-expandable-lines\"];\n if (!isExpandable) return;\n\n if (!node.properties) {\n node.properties = {};\n }\n\n node.properties[\"data-expandable\"] = \"true\";\n if (typeof expandableLines === \"string\" || typeof expandableLines === \"number\") {\n node.properties[\"data-expandable-lines\"] = expandableLines.toString();\n } else if (node.raw) {\n node.properties[\"data-expandable-lines\"] = countCodeLines(node.raw).toString();\n }\n\n const resolvedLanguage =\n languageFromProps ||\n languageFromMeta ||\n languageFromCodeClass ||\n existingPreLanguage ||\n node.language;\n const resolvedTitle = titleFromProps || titleFromMeta || existingPreTitle || node.codeTitle;\n\n if (resolvedLanguage) {\n node.properties[\"data-language\"] = resolvedLanguage;\n }\n if (resolvedTitle) {\n node.properties[\"data-title\"] = resolvedTitle;\n }\n\n const className = node.properties.className;\n if (!className) {\n node.properties.className = [];\n }\n\n if (Array.isArray(node.properties.className)) {\n if (!node.properties.className.includes(\"mdx-expandable-code\")) {\n node.properties.className.push(\"mdx-expandable-code\");\n }\n } else if (typeof className === \"string\") {\n const hasMarker = className.split(\" \").includes(\"mdx-expandable-code\");\n if (!hasMarker) {\n node.properties.className = `${className} mdx-expandable-code`.trim().split(\" \");\n }\n } else {\n node.properties.className = [\"mdx-expandable-code\"];\n }\n\n if (codeElement?.properties) {\n const cleanedCodeClassList = codeClassList.filter((item) => item !== \"mdx-expandable-meta\");\n codeElement.properties.className = cleanedCodeClassList;\n }\n });\n};\n","import type { Node, Parent } from \"unist\";\nimport { visit } from \"unist-util-visit\";\nimport type { ElementNode } from \"../utils\";\n\ninterface TextNode extends Node {\n type: \"text\";\n value: string;\n}\n\n/**\n * Rehype plugin that transforms `<pre><code class=\"language-mermaid\">` fenced\n * blocks into `<Mermaid chart=\"...\">` elements.\n *\n * This allows Mermaid diagram definitions to be authored via standard fenced\n * code blocks (````mermaid) which avoids JSX parsing collisions with\n * Mermaid's `{...}` (decision nodes) and `[...]` (label nodes) syntax.\n */\nexport const rehypeMermaid = () => (tree: Node) => {\n visit(tree, \"element\", (node: ElementNode, index: number | null, parent: Parent | null) => {\n if (!parent || index === null || node.tagName !== \"pre\") return;\n\n const codeEl = node.children?.find(\n (child) =>\n (child as ElementNode).type === \"element\" && (child as ElementNode).tagName === \"code\"\n ) as ElementNode | undefined;\n\n if (!codeEl) return;\n\n const classList = Array.isArray(codeEl.properties?.className)\n ? (codeEl.properties.className as string[])\n : typeof codeEl.properties?.className === \"string\"\n ? (codeEl.properties.className as string).split(\" \").filter(Boolean)\n : [];\n\n if (!classList.includes(\"language-mermaid\")) return;\n\n const textNode = codeEl.children?.find((child) => (child as TextNode).type === \"text\") as\n | TextNode\n | undefined;\n\n const chart = textNode?.value ?? \"\";\n\n parent.children[index] = {\n type: \"element\",\n tagName: \"Mermaid\",\n properties: { chart },\n children: [],\n } as unknown as ElementNode;\n });\n};\n","import matter from \"@11ty/gray-matter\";\nimport type { TocItem } from \"./types\";\n\nconst FENCE_MARKER_REGEX = /^(````|```)(?!`)/;\nconst HEADING_REGEX = /^(#{2,4})\\s+(.+)$/;\nconst RELEASE_VERSION_ATTR_REGEX = /\\bversion\\s*=\\s*\"([^\"]+)\"/;\n\nexport function sluggify(text: string): string {\n const normalized = text.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\"); // Remove accents\n const slug = normalized.toLowerCase().replace(/\\s+/g, \"-\");\n return slug.replace(/[^a-z0-9-]/g, \"\");\n}\n\nfunction parseReleaseVersionFromLine(line: string): string | null {\n const releaseStart = line.indexOf(\"<Release\");\n if (releaseStart === -1) {\n return null;\n }\n\n // Parse only the first tag fragment on the line to avoid broad regex scans.\n const fragment = line.slice(releaseStart, releaseStart + 512);\n const closingIndex = fragment.indexOf(\">\");\n if (closingIndex === -1) {\n return null;\n }\n\n const tag = fragment.slice(0, closingIndex + 1);\n if (!/^<Release\\b/.test(tag)) {\n return null;\n }\n\n const attrMatch = RELEASE_VERSION_ATTR_REGEX.exec(tag);\n const version = attrMatch?.[1] ?? \"\";\n return version.trim() || null;\n}\n\nexport function extractTocsFromRawMdx(rawMdx: string): TocItem[] {\n const extractedHeadings: TocItem[] = [];\n\n const lines = rawMdx.split(/\\r?\\n/);\n let inFence = false;\n let fenceLength = 0;\n\n for (const line of lines) {\n const trimmed = line.trimStart();\n\n const fenceMatch = FENCE_MARKER_REGEX.exec(trimmed);\n if (fenceMatch) {\n const marker = fenceMatch[1];\n\n if (!inFence) {\n inFence = true;\n fenceLength = marker.length;\n } else if (marker.length === fenceLength) {\n inFence = false;\n }\n\n continue;\n }\n\n if (inFence) {\n continue;\n }\n\n const headingMatch = HEADING_REGEX.exec(trimmed);\n if (headingMatch) {\n const headingLevel = headingMatch[1].length;\n const headingText = headingMatch[2].trim().replace(/\\s+#+\\s*$/, \"\");\n extractedHeadings.push({\n level: headingLevel,\n text: headingText,\n href: `#${sluggify(headingText)}`,\n });\n continue;\n }\n\n const version = parseReleaseVersionFromLine(line);\n if (version) {\n extractedHeadings.push({\n level: 2,\n text: `v${version}`,\n href: `#${version}`,\n });\n }\n }\n\n return extractedHeadings;\n}\n\nexport function extractFrontmatter<Frontmatter>(content: string): Frontmatter {\n try {\n return matter(content).data as Frontmatter;\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to extract frontmatter: ${reason}`);\n }\n}\n\n/**\n * Extract frontmatter and return both the parsed data and the content\n * with the frontmatter block stripped. Avoids a second parse by compileMDX.\n */\nexport function extractFrontmatterWithContent<Frontmatter>(content: string): {\n frontmatter: Frontmatter;\n strippedContent: string;\n} {\n try {\n const { data, content: strippedContent } = matter(content);\n return { frontmatter: data as Frontmatter, strippedContent };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to extract frontmatter: ${reason}`);\n }\n}\n","import path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport { extractFrontmatterWithContent, extractTocsFromRawMdx } from \"./extract\";\nimport { parseMdx, type ParseMdxOptions } from \"./compile\";\nimport type { MdxCompileResult, TocItem } from \"./types\";\n\ntype CacheFn = <T extends (...args: any[]) => any>(fn: T) => T;\n\nexport type ReadMdxFileResult = {\n content: string;\n /** Relative path used for UI links (e.g. \"docs/getting-started/index.mdx\"). */\n filePath: string;\n /** Absolute path on disk — available when file was read by readMdxFileBySlug. */\n absoluteFilePath?: string;\n};\n\nexport type ParsedMdxFile<Frontmatter, T extends TocItem = TocItem> = {\n /** Raw content with frontmatter block stripped — ready to pass to compileMDX. */\n content: string;\n filePath: string;\n frontmatter: Frontmatter;\n tocs: T[];\n};\n\nexport type CompiledMdxFile<\n Frontmatter,\n T extends TocItem = TocItem,\n> = MdxCompileResult<Frontmatter> & {\n filePath: string;\n tocs: T[];\n};\n\ntype ReadMdxBySlugOptions = {\n rootDir?: string;\n docsDir?: string;\n};\n\nexport async function readMdxFileBySlug(\n slug: string,\n options: ReadMdxBySlugOptions = {}\n): Promise<ReadMdxFileResult> {\n if (!slug || slug.trim() === \"\") {\n // Handle root slug as \"index\"\n slug = \"index\";\n }\n const docsDir = options.docsDir ?? \"docs\";\n // Keep file-system path operations ignored by Turbopack tracing.\n // The runtime path is constrained to docsDir and slug candidates below.\n const docsRoot = options.rootDir\n ? path.join(/*turbopackIgnore: true*/ options.rootDir, docsDir)\n : path.join(/*turbopackIgnore: true*/ process.cwd(), docsDir);\n\n // Resolve once for path-traversal guard — all candidate paths must stay\n // escaping the docs directory, especially important with dynamicParams=true.\n const resolvedRoot = path.resolve(/*turbopackIgnore: true*/ docsRoot);\n\n const paths = [\n path.join(/*turbopackIgnore: true*/ docsRoot, `${slug}.mdx`),\n path.join(/*turbopackIgnore: true*/ docsRoot, slug, \"index.mdx\"),\n ];\n // console.log(`Attempting to read slug: \"${slug}\", paths:`, paths); // Debug log\n\n for (const p of paths) {\n // Guard: reject any path that escapes the docs root.\n const resolvedP = path.resolve(/*turbopackIgnore: true*/ p);\n if (!resolvedP.startsWith(resolvedRoot + path.sep) && resolvedP !== resolvedRoot) {\n continue;\n }\n\n try {\n const content = await fs.readFile(/*turbopackIgnore: true*/ p, \"utf-8\");\n return {\n content,\n filePath: `${docsDir}/${path.relative(/*turbopackIgnore: true*/ docsRoot, p)}`,\n absoluteFilePath: p,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n throw error;\n }\n }\n\n throw new Error(\"Could not find mdx file for the requested slug.\");\n}\n\ntype ParseMdxFileOptions<T extends TocItem> = {\n tocsExtractor?: (rawMdx: string) => T[];\n};\n\nexport function parseMdxFile<Frontmatter, T extends TocItem = TocItem>(\n raw: ReadMdxFileResult,\n options: ParseMdxFileOptions<T> = {}\n): ParsedMdxFile<Frontmatter, T> {\n const tocsExtractor = options.tocsExtractor ?? ((mdx) => extractTocsFromRawMdx(mdx) as T[]);\n // Extract frontmatter and stripped content in one gray-matter call.\n // strippedContent is passed to compileMDX so it doesn't need to re-parse frontmatter.\n const { frontmatter, strippedContent } = extractFrontmatterWithContent<Frontmatter>(raw.content);\n\n return {\n content: strippedContent,\n filePath: raw.filePath,\n frontmatter,\n tocs: tocsExtractor(raw.content),\n };\n}\n\nexport async function compileParsedMdxFile<Frontmatter, T extends TocItem = TocItem>(\n parsed: ParsedMdxFile<Frontmatter, T>,\n options: ParseMdxOptions = {}\n): Promise<CompiledMdxFile<Frontmatter, T>> {\n // Content in parsed is already stripped of frontmatter by parseMdxFile.\n // Set parseFrontmatter:false — no re-parse needed, avoids double work.\n const compiled = await parseMdx<Frontmatter>(parsed.content, {\n ...options,\n parseFrontmatter: false,\n });\n\n return {\n ...compiled,\n frontmatter: parsed.frontmatter,\n filePath: parsed.filePath,\n tocs: parsed.tocs,\n };\n}\n\nexport type CreateMdxContentServiceOptions<Frontmatter, T extends TocItem = TocItem> = {\n parseOptions?: ParseMdxOptions;\n readOptions?: ReadMdxBySlugOptions;\n tocsExtractor?: (rawMdx: string) => T[];\n cacheFn?: CacheFn;\n /**\n * Optional hook to enrich or transform frontmatter after parsing.\n * Called with the parsed frontmatter and the absolute file path.\n * Runs at build time during static generation — ideal for injecting\n * fallback values (e.g. git last-modified date when `date` is absent).\n */\n frontmatterEnricher?: (\n frontmatter: Frontmatter,\n absoluteFilePath: string\n ) => Frontmatter | Promise<Frontmatter>;\n};\n\nexport function createMdxContentService<Frontmatter, T extends TocItem = TocItem>(\n options: CreateMdxContentServiceOptions<Frontmatter, T> = {}\n) {\n const identityCache: CacheFn = (fn) => fn;\n const cacheFn = options.cacheFn ?? identityCache;\n\n const getParsedForSlug = cacheFn(async (slug: string): Promise<ParsedMdxFile<Frontmatter, T>> => {\n const raw = await readMdxFileBySlug(slug, options.readOptions);\n const parsed = parseMdxFile<Frontmatter, T>(raw, { tocsExtractor: options.tocsExtractor });\n if (options.frontmatterEnricher && raw.absoluteFilePath) {\n parsed.frontmatter = await options.frontmatterEnricher(\n parsed.frontmatter,\n raw.absoluteFilePath\n );\n }\n return parsed;\n });\n\n const getCompiledForSlug = cacheFn(\n async (slug: string): Promise<CompiledMdxFile<Frontmatter, T>> => {\n const parsed = await getParsedForSlug(slug);\n return compileParsedMdxFile<Frontmatter, T>(parsed, options.parseOptions);\n }\n );\n\n async function getFrontmatterForSlug(slug: string): Promise<Frontmatter> {\n const parsed = await getParsedForSlug(slug);\n return parsed.frontmatter;\n }\n\n async function getTocsForSlug(slug: string): Promise<T[]> {\n const parsed = await getParsedForSlug(slug);\n return parsed.tocs;\n }\n\n return {\n getParsedForSlug,\n getCompiledForSlug,\n getFrontmatterForSlug,\n getTocsForSlug,\n };\n}\n"],"mappings":"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","names":["visit","visit","visit","visit"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docubook/core",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"description": "Shared MDX compile pipeline and markdown utilities for DocuBook",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
"author-url": "https://wildan.dev",
|
|
40
40
|
"license": "MIT",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@11ty/gray-matter": "^2.0
|
|
42
|
+
"@11ty/gray-matter": "^2.1.0",
|
|
43
43
|
"clsx": "^2.1.1",
|
|
44
|
-
"next-mdx-remote": "^6.0.0",
|
|
45
44
|
"rehype-autolink-headings": "^7.1.0",
|
|
46
45
|
"rehype-code-titles": "^1.2.1",
|
|
47
46
|
"rehype-prism-plus": "^2.0.2",
|
|
48
47
|
"rehype-slug": "^6.0.0",
|
|
49
48
|
"remark-gfm": "^4.0.1",
|
|
50
49
|
"tailwind-merge": "^3.6.0",
|
|
51
|
-
"unist-util-visit": "^5.1.0"
|
|
50
|
+
"unist-util-visit": "^5.1.0",
|
|
51
|
+
"@docubook/mdx-remote": "^1.0.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^20.19.37",
|