|
| 1 | +type fileData = { |
| 2 | + content: string, |
| 3 | + frontmatter: JSON.t, |
| 4 | +} |
| 5 | + |
| 6 | +type compileInput = {value: string, path: string} |
| 7 | +type compileOptions = { |
| 8 | + outputFormat: string, |
| 9 | + remarkPlugins: array<Mdx.remarkPlugin>, |
| 10 | +} |
| 11 | +@module("@mdx-js/mdx") |
| 12 | +external compile: (compileInput, compileOptions) => promise<CompiledMdx.compileResult> = "compile" |
| 13 | + |
| 14 | +@module("remark-frontmatter") external remarkFrontmatter: Mdx.remarkPlugin = "default" |
| 15 | + |
| 16 | +let compileMdx = async (content, ~filePath, ~remarkPlugins=[]) => { |
| 17 | + let compiled = await compile( |
| 18 | + {value: content, path: filePath}, |
| 19 | + { |
| 20 | + outputFormat: "function-body", |
| 21 | + remarkPlugins: [remarkFrontmatter, ...remarkPlugins], |
| 22 | + }, |
| 23 | + ) |
| 24 | + compiled->CompiledMdx.fromCompileResult |
| 25 | +} |
| 26 | + |
| 27 | +let resolveFilePath = (pathname, ~dir, ~alias) => { |
| 28 | + let path = if pathname->String.startsWith("/") { |
| 29 | + pathname->String.slice(~start=1, ~end=String.length(pathname)) |
| 30 | + } else { |
| 31 | + pathname |
| 32 | + } |
| 33 | + let relativePath = |
| 34 | + if path->String.startsWith(alias ++ "/") { |
| 35 | + let rest = path->String.slice(~start=String.length(alias) + 1, ~end=String.length(path)) |
| 36 | + Node.Path.join2(dir, rest) |
| 37 | + } else if path->String.startsWith(alias) { |
| 38 | + let rest = path->String.slice(~start=String.length(alias), ~end=String.length(path)) |
| 39 | + Node.Path.join2(dir, rest) |
| 40 | + } else { |
| 41 | + path |
| 42 | + } |
| 43 | + relativePath ++ ".mdx" |
| 44 | +} |
| 45 | + |
| 46 | +let loadFile = async filePath => { |
| 47 | + let raw = await Node.Fs.readFile(filePath, "utf-8") |
| 48 | + let {frontmatter, content}: MarkdownParser.result = MarkdownParser.parseSync(raw) |
| 49 | + {content, frontmatter} |
| 50 | +} |
| 51 | + |
| 52 | +// Recursively scan a directory for .mdx files |
| 53 | +let rec scanDir = (baseDir, currentDir) => { |
| 54 | + let entries = Node.Fs.readdirSync(currentDir) |
| 55 | + entries->Array.flatMap(entry => { |
| 56 | + let fullPath = Node.Path.join2(currentDir, entry) |
| 57 | + if Node.Fs.statSync(fullPath)["isDirectory"]() { |
| 58 | + scanDir(baseDir, fullPath) |
| 59 | + } else if Node.Path.extname(entry) === ".mdx" { |
| 60 | + // Get the relative path from baseDir |
| 61 | + let relativePath = |
| 62 | + fullPath |
| 63 | + ->String.replaceAll("\\", "/") |
| 64 | + ->String.replace(baseDir->String.replaceAll("\\", "/") ++ "/", "") |
| 65 | + ->String.replace(".mdx", "") |
| 66 | + [relativePath] |
| 67 | + } else { |
| 68 | + [] |
| 69 | + } |
| 70 | + }) |
| 71 | +} |
| 72 | + |
| 73 | +let scanPaths = (~dir, ~alias) => { |
| 74 | + scanDir(dir, dir)->Array.map(relativePath => { |
| 75 | + alias ++ "/" ++ relativePath |
| 76 | + }) |
| 77 | +} |
0 commit comments