@docubook/core 1.8.2 → 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,10 +6,11 @@ import {
6
6
  stringToDate,
7
7
  toIsoDateOnly
8
8
  } from "./chunk-HZJLRYAI.js";
9
+ import {
10
+ serialize
11
+ } from "./chunk-J7CN2VUH.js";
9
12
 
10
13
  // src/compile.ts
11
- import { compileMDX } from "@docubook/mdx-remote/rsc";
12
- import { serialize } from "@docubook/mdx-remote/serialize";
13
14
  import { visit as visit4 } from "unist-util-visit";
14
15
  import remarkGfm from "remark-gfm";
15
16
  import rehypePrism from "rehype-prism-plus";
@@ -200,8 +201,120 @@ var rehypeMermaid = () => (tree) => {
200
201
  });
201
202
  };
202
203
 
204
+ // src/plugins/remarkDirectiveToMdx.ts
205
+ function remarkDirectiveToMdx() {
206
+ return (tree) => {
207
+ const root = tree;
208
+ root.children = root.children.map(transform);
209
+ return tree;
210
+ };
211
+ }
212
+ var PURE_LEAVES = /* @__PURE__ */ new Set(["youtube"]);
213
+ function isDirective(node) {
214
+ return node.type === "containerDirective" || node.type === "leafDirective" || node.type === "textDirective";
215
+ }
216
+ function transform(node) {
217
+ if (!isDirective(node)) {
218
+ const children2 = node.children;
219
+ if (Array.isArray(children2)) {
220
+ node.children = children2.map(transform);
221
+ }
222
+ return node;
223
+ }
224
+ if (node.type === "textDirective") {
225
+ if (node.name === "tooltip") {
226
+ return inlineTooltip(node);
227
+ }
228
+ return literalDirective(node);
229
+ }
230
+ if (node.type === "leafDirective" && node.name === "tooltip") {
231
+ return literalDirective(node);
232
+ }
233
+ const children = node.type === "containerDirective" && !PURE_LEAVES.has(node.name) ? (node.children ?? []).map(transform) : [];
234
+ return directiveToElement(node, children);
235
+ }
236
+ function directiveToElement(directive, children) {
237
+ const name = pascalCase(directive.name);
238
+ const attributes = Object.entries(directive.attributes ?? {}).map(([attrName, value]) => ({
239
+ type: "mdxJsxAttribute",
240
+ name: attrName,
241
+ value: value === "" ? null : value
242
+ }));
243
+ return {
244
+ type: "mdxJsxFlowElement",
245
+ name,
246
+ attributes,
247
+ children
248
+ };
249
+ }
250
+ function literalDirective(directive) {
251
+ const literal = ":" + directive.name + (directive.label ? `[${directive.label}]` : "");
252
+ const attrStr = Object.entries(directive.attributes ?? {}).map(([k, v]) => v === "" ? k : `${k}="${v}"`).join(" ");
253
+ return { type: "text", value: literal + (attrStr ? `{${attrStr}}` : "") };
254
+ }
255
+ function inlineTooltip(directive) {
256
+ const label = (directive.children ?? []).map((child) => child.value ?? "").join("");
257
+ const attrs = directive.attributes ?? {};
258
+ const attributes = [
259
+ { type: "mdxJsxAttribute", name: "text", value: attrs.text || label || "?" },
260
+ { type: "mdxJsxAttribute", name: "tip", value: attrs.tip || label || "" }
261
+ ];
262
+ return { type: "mdxJsxTextElement", name: "Tooltip", attributes, children: [] };
263
+ }
264
+ function pascalCase(name) {
265
+ return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
266
+ }
267
+
268
+ // src/compile.ts
269
+ import remarkDirective from "remark-directive";
270
+
271
+ // src/mdx-compiler/index.ts
272
+ import React, { useEffect, useState, useMemo } from "react";
273
+ import * as jsxRuntime from "react/jsx-runtime";
274
+ import * as jsxDevRuntime from "react/jsx-dev-runtime";
275
+ import * as mdx from "@mdx-js/react";
276
+ function MDXRemote({
277
+ compiledSource,
278
+ frontmatter,
279
+ scope = {},
280
+ components = {},
281
+ lazy
282
+ }) {
283
+ const [ready, setReady] = useState(!lazy || typeof window === "undefined");
284
+ useEffect(() => {
285
+ if (!lazy) return;
286
+ const id = window.requestIdleCallback ? window.requestIdleCallback(() => setReady(true), { timeout: 500 }) : setTimeout(() => setReady(true), 1);
287
+ return () => {
288
+ if (window.cancelIdleCallback) window.cancelIdleCallback(id);
289
+ else clearTimeout(id);
290
+ };
291
+ }, [lazy]);
292
+ const Content = useMemo(() => {
293
+ const fullScope = {
294
+ opts: { ...mdx, ...jsxRuntime, ...jsxDevRuntime },
295
+ frontmatter,
296
+ ...scope
297
+ };
298
+ const keys = Object.keys(fullScope);
299
+ const values = Object.values(fullScope);
300
+ const fn = Reflect.construct(Function, keys.concat(`${compiledSource}`));
301
+ return fn.apply(fn, values).default;
302
+ }, [compiledSource, scope, frontmatter]);
303
+ if (!ready) {
304
+ return React.createElement("div", {
305
+ dangerouslySetInnerHTML: { __html: "" },
306
+ suppressHydrationWarning: true
307
+ });
308
+ }
309
+ const content = React.createElement(
310
+ mdx.MDXProvider,
311
+ { components },
312
+ React.createElement(Content, null)
313
+ );
314
+ return lazy ? React.createElement("div", null, content) : content;
315
+ }
316
+
203
317
  // src/compile.ts
204
- import { MDXRemote } from "@docubook/mdx-remote";
205
318
  var preProcess = () => (tree) => {
206
319
  visit4(tree, (node) => {
207
320
  const element = node;
@@ -257,52 +370,18 @@ function createDefaultRehypePlugins() {
257
370
  ];
258
371
  }
259
372
  function createDefaultRemarkPlugins() {
260
- return [remarkGfm, handleCodeExpandableRemark];
261
- }
262
- async function parseMdx(rawMdx, options = {}) {
263
- const rehypePlugins = options.rehypePlugins ?? createDefaultRehypePlugins();
264
- const remarkPlugins = options.remarkPlugins ?? createDefaultRemarkPlugins();
265
- return await compileMDX({
266
- source: rawMdx,
267
- options: {
268
- parseFrontmatter: options.parseFrontmatter ?? true,
269
- mdxOptions: {
270
- rehypePlugins,
271
- remarkPlugins
272
- }
273
- },
274
- components: options.components
275
- });
373
+ return [remarkGfm, handleCodeExpandableRemark, remarkDirective, remarkDirectiveToMdx];
276
374
  }
277
375
 
278
376
  // src/extract.ts
279
377
  import matter from "@11ty/gray-matter";
280
378
  var FENCE_MARKER_REGEX = /^(````|```)(?!`)/;
281
379
  var HEADING_REGEX = /^(#{2,4})\s+(.+)$/;
282
- var RELEASE_VERSION_ATTR_REGEX = /\bversion\s*=\s*"([^"]+)"/;
283
380
  function sluggify(text) {
284
381
  const normalized = text.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
285
382
  const slug = normalized.toLowerCase().replace(/\s+/g, "-");
286
383
  return slug.replace(/[^a-z0-9-]/g, "");
287
384
  }
288
- function parseReleaseVersionFromLine(line) {
289
- const releaseStart = line.indexOf("<Release");
290
- if (releaseStart === -1) {
291
- return null;
292
- }
293
- const fragment = line.slice(releaseStart, releaseStart + 512);
294
- const closingIndex = fragment.indexOf(">");
295
- if (closingIndex === -1) {
296
- return null;
297
- }
298
- const tag = fragment.slice(0, closingIndex + 1);
299
- if (!/^<Release\b/.test(tag)) {
300
- return null;
301
- }
302
- const attrMatch = RELEASE_VERSION_ATTR_REGEX.exec(tag);
303
- const version = attrMatch?.[1] ?? "";
304
- return version.trim() || null;
305
- }
306
385
  function extractTocsFromRawMdx(rawMdx) {
307
386
  const extractedHeadings = [];
308
387
  const lines = rawMdx.split(/\r?\n/);
@@ -335,14 +414,6 @@ function extractTocsFromRawMdx(rawMdx) {
335
414
  });
336
415
  continue;
337
416
  }
338
- const version = parseReleaseVersionFromLine(line);
339
- if (version) {
340
- extractedHeadings.push({
341
- level: 2,
342
- text: `v${version}`,
343
- href: `#${version}`
344
- });
345
- }
346
417
  }
347
418
  return extractedHeadings;
348
419
  }
@@ -351,147 +422,26 @@ function extractFrontmatter(content) {
351
422
  return matter(content).data;
352
423
  } catch (error) {
353
424
  const reason = error instanceof Error ? error.message : String(error);
354
- throw new Error(`Failed to extract frontmatter: ${reason}`);
425
+ throw new Error(`Failed to extract frontmatter: ${reason}`, { cause: error });
355
426
  }
356
427
  }
357
- function extractFrontmatterWithContent(content) {
428
+ function extractFrontmatterWithContent(content, schema) {
358
429
  try {
359
430
  const { data, content: strippedContent } = matter(content);
360
- return { frontmatter: data, strippedContent };
431
+ return {
432
+ frontmatter: schema ? schema.parse(data) : data,
433
+ strippedContent
434
+ };
361
435
  } catch (error) {
362
436
  const reason = error instanceof Error ? error.message : String(error);
363
- throw new Error(`Failed to extract frontmatter: ${reason}`);
364
- }
365
- }
366
-
367
- // src/content.ts
368
- import path from "node:path";
369
- import { promises as fs } from "node:fs";
370
- async function readMdxFileBySlug(slug, options = {}) {
371
- if (!slug || slug.trim() === "") {
372
- slug = "index";
373
- }
374
- const docsDir = options.docsDir ?? "docs";
375
- const docsRoot = options.rootDir ? path.join(
376
- /*turbopackIgnore: true*/
377
- options.rootDir,
378
- docsDir
379
- ) : path.join(
380
- /*turbopackIgnore: true*/
381
- process.cwd(),
382
- docsDir
383
- );
384
- const resolvedRoot = path.resolve(
385
- /*turbopackIgnore: true*/
386
- docsRoot
387
- );
388
- const paths = [
389
- path.join(
390
- /*turbopackIgnore: true*/
391
- docsRoot,
392
- `${slug}.mdx`
393
- ),
394
- path.join(
395
- /*turbopackIgnore: true*/
396
- docsRoot,
397
- slug,
398
- "index.mdx"
399
- )
400
- ];
401
- for (const p of paths) {
402
- const resolvedP = path.resolve(
403
- /*turbopackIgnore: true*/
404
- p
405
- );
406
- if (!resolvedP.startsWith(resolvedRoot + path.sep) && resolvedP !== resolvedRoot) {
407
- continue;
408
- }
409
- try {
410
- const content = await fs.readFile(
411
- /*turbopackIgnore: true*/
412
- p,
413
- "utf-8"
414
- );
415
- return {
416
- content,
417
- filePath: `${docsDir}/${path.relative(
418
- /*turbopackIgnore: true*/
419
- docsRoot,
420
- p
421
- )}`,
422
- absoluteFilePath: p
423
- };
424
- } catch (error) {
425
- if (error.code === "ENOENT") continue;
426
- throw error;
427
- }
437
+ throw new Error(`Failed to extract frontmatter: ${reason}`, { cause: error });
428
438
  }
429
- throw new Error("Could not find mdx file for the requested slug.");
430
- }
431
- function parseMdxFile(raw, options = {}) {
432
- const tocsExtractor = options.tocsExtractor ?? ((mdx) => extractTocsFromRawMdx(mdx));
433
- const { frontmatter, strippedContent } = extractFrontmatterWithContent(raw.content);
434
- return {
435
- content: strippedContent,
436
- filePath: raw.filePath,
437
- frontmatter,
438
- tocs: tocsExtractor(raw.content)
439
- };
440
- }
441
- async function compileParsedMdxFile(parsed, options = {}) {
442
- const compiled = await parseMdx(parsed.content, {
443
- ...options,
444
- parseFrontmatter: false
445
- });
446
- return {
447
- ...compiled,
448
- frontmatter: parsed.frontmatter,
449
- filePath: parsed.filePath,
450
- tocs: parsed.tocs
451
- };
452
- }
453
- function createMdxContentService(options = {}) {
454
- const identityCache = (fn) => fn;
455
- const cacheFn = options.cacheFn ?? identityCache;
456
- const getParsedForSlug = cacheFn(async (slug) => {
457
- const raw = await readMdxFileBySlug(slug, options.readOptions);
458
- const parsed = parseMdxFile(raw, { tocsExtractor: options.tocsExtractor });
459
- if (options.frontmatterEnricher && raw.absoluteFilePath) {
460
- parsed.frontmatter = await options.frontmatterEnricher(
461
- parsed.frontmatter,
462
- raw.absoluteFilePath
463
- );
464
- }
465
- return parsed;
466
- });
467
- const getCompiledForSlug = cacheFn(
468
- async (slug) => {
469
- const parsed = await getParsedForSlug(slug);
470
- return compileParsedMdxFile(parsed, options.parseOptions);
471
- }
472
- );
473
- async function getFrontmatterForSlug(slug) {
474
- const parsed = await getParsedForSlug(slug);
475
- return parsed.frontmatter;
476
- }
477
- async function getTocsForSlug(slug) {
478
- const parsed = await getParsedForSlug(slug);
479
- return parsed.tocs;
480
- }
481
- return {
482
- getParsedForSlug,
483
- getCompiledForSlug,
484
- getFrontmatterForSlug,
485
- getTocsForSlug
486
- };
487
439
  }
488
440
  export {
489
441
  MDXRemote,
490
442
  cn,
491
- compileParsedMdxFile,
492
443
  createDefaultRehypePlugins,
493
444
  createDefaultRemarkPlugins,
494
- createMdxContentService,
495
445
  extractFrontmatter,
496
446
  extractFrontmatterWithContent,
497
447
  extractTocsFromRawMdx,
@@ -501,12 +451,10 @@ export {
501
451
  handleCodeExpandableRemark,
502
452
  handleCodeTitles,
503
453
  parseDate,
504
- parseMdx,
505
- parseMdxFile,
506
454
  postProcess,
507
455
  preProcess,
508
- readMdxFileBySlug,
509
456
  rehypeMermaid,
457
+ remarkDirectiveToMdx,
510
458
  serialize,
511
459
  sluggify,
512
460
  stringToDate,
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 \"@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"]}
1
+ {"version":3,"sources":["../src/compile.ts","../src/plugins/handleCodeTitles.ts","../src/plugins/handleCodeExpandable.ts","../src/plugins/rehypeMermaid.ts","../src/plugins/remarkDirectiveToMdx.ts","../src/mdx-compiler/index.ts","../src/extract.ts"],"sourcesContent":["import { serialize } from \"./mdx-compiler/serialize.js\";\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 { remarkDirectiveToMdx } from \"./plugins/remarkDirectiveToMdx\";\nimport remarkDirective from \"remark-directive\";\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 \"./mdx-compiler/index.js\";\n\ninterface TextNode extends Node {\n type: \"text\";\n value: string;\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, remarkDirective, remarkDirectiveToMdx];\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 | 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 type { Node } from \"unist\";\n\n/**\n * Remark plugin: convert markdown directives into MDX component elements.\n *\n * Contract (docubook):\n * - `:::name{attrs} … :::` — container: EVERY component that holds content\n * (tabs, tab, accordions, accordion, steps, step, cards, card, files,\n * folder, note + variants). Children are the block between the opening\n * `:::` and closing `:::` — bounded by micromark's container grammar, so\n * a component can never trap siblings that follow it.\n * - `::name{attrs}` — self-closing leaf (no children): file, youtube,\n * mermaid.\n * - `:tooltip[label]{tip=\"…\"}` — the ONE inline (single-colon) directive.\n * Every other text directive is rebuilt as literal text\n * (`localhost:3000` stays intact). `::tooltip` (block leaf) is removed\n * in v2 — tooltips are inline only.\n *\n * Names are PascalCased to match the components map (`file-tree` → `FileTree`).\n * Bare attributes (`{horizontal}`) become boolean props (JSX bare attribute).\n * Callout variants (`:::tip`, `:::info`, …) map to their own registry entries\n * (`Tip`/`Info`/…) which wrap the `Callout` component with the type set.\n */\nexport function remarkDirectiveToMdx() {\n return (tree: Node) => {\n const root = tree as unknown as { children: Node[] };\n root.children = root.children.map(transform);\n return tree;\n };\n}\n\n/** Leaves that never hold children (self-closing). */\nconst PURE_LEAVES = new Set([\"youtube\"]);\n\ntype DirectiveNode = Node & {\n type: \"containerDirective\" | \"leafDirective\" | \"textDirective\";\n name: string;\n label?: string;\n attributes?: Record<string, string>;\n children?: Node[];\n};\n\nfunction isDirective(node: Node): node is DirectiveNode {\n return (\n node.type === \"containerDirective\" ||\n node.type === \"leafDirective\" ||\n node.type === \"textDirective\"\n );\n}\n\nfunction transform(node: Node): Node {\n if (!isDirective(node)) {\n const children = (node as unknown as { children?: Node[] }).children;\n if (Array.isArray(children)) {\n (node as unknown as { children: Node[] }).children = children.map(transform);\n }\n return node;\n }\n if (node.type === \"textDirective\") {\n // `:tooltip[label]{tip=\"…\"}` is the one inline component — it stays\n // inside the paragraph. Every other single-colon text directive is\n // rebuilt as literal text (`localhost:3000` stays intact).\n if (node.name === \"tooltip\") {\n return inlineTooltip(node);\n }\n return literalDirective(node);\n }\n // Block-form tooltips are gone in v2 — degrade to literal text so the\n // author sees the directive instead of a broken component.\n if (node.type === \"leafDirective\" && node.name === \"tooltip\") {\n return literalDirective(node);\n }\n // containerDirective → component with children; leafDirective → self-closing.\n const children =\n node.type === \"containerDirective\" && !PURE_LEAVES.has(node.name)\n ? (node.children ?? []).map(transform)\n : [];\n return directiveToElement(node, children);\n}\n\nfunction directiveToElement(directive: DirectiveNode, children: Node[]): Node {\n const name = pascalCase(directive.name);\n const attributes = Object.entries(directive.attributes ?? {}).map(([attrName, value]) => ({\n type: \"mdxJsxAttribute\",\n name: attrName,\n value: value === \"\" ? null : value,\n }));\n return {\n type: \"mdxJsxFlowElement\",\n name,\n attributes,\n children,\n } as Node;\n}\n\n/** Rebuild a text directive as literal text (single-colon is not a contract). */\nfunction literalDirective(directive: DirectiveNode): Node {\n const literal = \":\" + directive.name + (directive.label ? `[${directive.label}]` : \"\");\n const attrStr = Object.entries(directive.attributes ?? {})\n .map(([k, v]) => (v === \"\" ? k : `${k}=\"${v}\"`))\n .join(\" \");\n return { type: \"text\", value: literal + (attrStr ? `{${attrStr}}` : \"\") } as Node;\n}\n\n/**\n * Inline tooltip from a text directive: `:tooltip[label]{tip=\"…\"}`.\n * The label is the visible trigger (dotted underline); `tip` is the hover\n * bubble and defaults to the label, so `:tooltip[text]` alone already shows\n * a bubble. Emits an inline element so it stays inside the paragraph. The\n * bubble auto-positions (no `side` prop).\n */\nfunction inlineTooltip(directive: DirectiveNode): Node {\n const label = (directive.children ?? [])\n .map((child) => (child as { value?: string }).value ?? \"\")\n .join(\"\");\n const attrs = directive.attributes ?? {};\n const attributes = [\n { type: \"mdxJsxAttribute\", name: \"text\", value: attrs.text || label || \"?\" },\n { type: \"mdxJsxAttribute\", name: \"tip\", value: attrs.tip || label || \"\" },\n ];\n return { type: \"mdxJsxTextElement\", name: \"Tooltip\", attributes, children: [] } as Node;\n}\n\nfunction pascalCase(name: string): string {\n return name\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n}\n","// MPL-2.0 — derived from next-mdx-remote (IBM). See LICENSE-MPL-2.0.\nimport React, { useEffect, useState, useMemo } from \"react\";\nimport * as jsxRuntime from \"react/jsx-runtime\";\nimport * as jsxDevRuntime from \"react/jsx-dev-runtime\";\nimport * as mdx from \"@mdx-js/react\";\nimport type { MDXRemoteSerializeResult } from \"./types.js\";\n\n/** Props for the client-side `<MDXRemote>` (accepts pre-serialized result). */\nexport type MDXRemoteProps = MDXRemoteSerializeResult & {\n components?: Record<string, React.ComponentType<any>>;\n /** Defer hydration to an idle callback */\n lazy?: boolean;\n};\n\n/**\n * Client-side MDX renderer.\n *\n * Accepts a pre-compiled result from `serialize()` and renders it via\n * `MDXProvider` for custom component injection.\n */\nexport function MDXRemote({\n compiledSource,\n frontmatter,\n scope = {},\n components = {},\n lazy,\n}: MDXRemoteProps) {\n const [ready, setReady] = useState(!lazy || typeof window === \"undefined\");\n\n useEffect(() => {\n if (!lazy) return;\n const id = window.requestIdleCallback\n ? window.requestIdleCallback(() => setReady(true), { timeout: 500 })\n : setTimeout(() => setReady(true), 1);\n return () => {\n if (window.cancelIdleCallback) window.cancelIdleCallback(id as number);\n else clearTimeout(id as number);\n };\n }, [lazy]);\n\n const Content = useMemo(() => {\n // Non-RSC mode: compiled MDX expects `useMDXComponents` (\n // from @mdx-js/react) AND the JSX runtime.\n // In React 19, jsx/jsxs and jsxDEV live in separate modules,\n // so merge both to handle compiled output from any mode.\n const fullScope = {\n opts: { ...mdx, ...jsxRuntime, ...jsxDevRuntime },\n frontmatter,\n ...scope,\n };\n const keys = Object.keys(fullScope);\n const values = Object.values(fullScope);\n const fn = Reflect.construct(Function, keys.concat(`${compiledSource}`));\n return fn.apply(fn, values).default;\n }, [compiledSource, scope, frontmatter]);\n\n if (!ready) {\n return React.createElement(\"div\", {\n dangerouslySetInnerHTML: { __html: \"\" },\n suppressHydrationWarning: true,\n });\n }\n\n const content = React.createElement(\n mdx.MDXProvider,\n { components },\n React.createElement(Content, null)\n );\n\n return lazy ? React.createElement(\"div\", null, content) : content;\n}\n","import matter from \"@11ty/gray-matter\";\nimport type { ZodType } from \"zod\";\nimport type { TocItem } from \"./types\";\n\nconst FENCE_MARKER_REGEX = /^(````|```)(?!`)/;\nconst HEADING_REGEX = /^(#{2,4})\\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\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\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}`, { cause: error });\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 during\n * compilation.\n *\n * Optionally validates the parsed frontmatter with a Zod schema.\n * YAML coerces unquoted values (e.g. `date: 2026-06-10` → Date, `3.5` → number),\n * so use `z.coerce.*` for fields that must remain strings.\n */\nexport function extractFrontmatterWithContent<Frontmatter>(content: string): {\n frontmatter: Frontmatter;\n strippedContent: string;\n};\nexport function extractFrontmatterWithContent<Frontmatter>(\n content: string,\n schema: ZodType<Frontmatter>\n): { frontmatter: Frontmatter; strippedContent: string };\nexport function extractFrontmatterWithContent<Frontmatter>(\n content: string,\n schema?: ZodType<Frontmatter>\n): { frontmatter: Frontmatter; strippedContent: string } {\n try {\n const { data, content: strippedContent } = matter(content);\n return {\n frontmatter: schema ? schema.parse(data) : (data as Frontmatter),\n strippedContent,\n };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to extract frontmatter: ${reason}`, { cause: error });\n }\n}\n"],"mappings":"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","names":["visit","visit","visit","children","visit"]}
@@ -0,0 +1,53 @@
1
+ import { Pluggable } from 'unified';
2
+
3
+ /** Shape returned by `serialize()` — ready to pass to `<MDXRemote>`. */
4
+ type MDXRemoteSerializeResult = SerializeResult;
5
+
6
+ /** @internal — re-exported from unified. */
7
+ type RemarkPlugins = Pluggable[];
8
+ type RehypePlugins = Pluggable[];
9
+
10
+ type SerializeOptions = {
11
+ scope?: Record<string, unknown>;
12
+ mdxOptions?: {
13
+ remarkPlugins?: RemarkPlugins;
14
+ rehypePlugins?: RehypePlugins;
15
+ };
16
+ parseFrontmatter?: boolean;
17
+ /**
18
+ * MDX compile output shape.
19
+ * - `"function-body"` (default): JS function body string for `<MDXRemote>`.
20
+ * - `"program"`: full ESM module source (imports + `export default MDXContent`)
21
+ * for static bundling / hydration without `new Function`.
22
+ * @default "function-body"
23
+ */
24
+ outputFormat?: "function-body" | "program";
25
+ /**
26
+ * MDX input format.
27
+ * - `"mdx"` (default): JSX tags are parsed and resolve via the components map.
28
+ * - `"md"`: plain markdown — authored JSX tags are NOT parsed (dropped,
29
+ * content kept as text). Markdown directives (`:::`/`::`/`::::`) still
30
+ * work; this is the v2 authoring contract (no JSX tags).
31
+ * @default "mdx"
32
+ */
33
+ format?: "mdx" | "md";
34
+ /**
35
+ * Strip JavaScript expressions from MDX (default: true).
36
+ * When true, removes all `{expression}` and JSX attribute expression nodes
37
+ * before compilation. When false, expressions are preserved but a
38
+ * security sanitizer audits the AST for dangerous patterns.
39
+ * @default true
40
+ */
41
+ blockJS?: boolean;
42
+ };
43
+ type SerializeResult = {
44
+ compiledSource: string;
45
+ frontmatter: Record<string, unknown>;
46
+ scope: Record<string, unknown>;
47
+ };
48
+ /**
49
+ * Compile raw MDX string into a serialized result that can be rendered.
50
+ */
51
+ declare function serialize(source: string, { scope, mdxOptions, parseFrontmatter, blockJS, outputFormat, format, }?: SerializeOptions, rsc?: boolean): Promise<SerializeResult>;
52
+
53
+ export { type MDXRemoteSerializeResult, type SerializeOptions, type SerializeResult, serialize };
@@ -0,0 +1,7 @@
1
+ import {
2
+ serialize
3
+ } from "../chunk-J7CN2VUH.js";
4
+ export {
5
+ serialize
6
+ };
7
+ //# sourceMappingURL=serialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}