MDX: Hotfix Windows EOL being ignored

This commit is contained in:
Fuma Nama
2025-06-16 22:04:56 +08:00
parent 7d1ac21961
commit cd86f58c14
5 changed files with 61 additions and 37 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-mdx': patch
---
Hotfix Windows EOL being ignored
+7 -36
View File
@@ -1,58 +1,29 @@
/**
* Inspired by https://github.com/jonschlinkert/gray-matter
*/
import { LRUCache } from 'lru-cache';
import { load } from 'js-yaml';
const cache = new LRUCache<string, Output>({
max: 200,
});
interface Output {
matter: string;
content: string;
data: unknown;
}
const regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
/**
* parse frontmatter, it supports only yaml format
*/
export function fumaMatter(input: string): Output {
if (input === '') {
return { data: {}, content: input, matter: '' };
}
const cached = cache.get(input);
if (cached) return cached;
const result = parseMatter(input);
cache.set(input, result);
// avoid mutation
return structuredClone(result);
}
const delimiter = '---';
function parseMatter(str: string): Output {
const output: Output = { matter: '', data: {}, content: str };
const open = delimiter + '\n';
const close = '\n' + delimiter;
if (!str.startsWith(open)) {
const output: Output = { matter: '', data: {}, content: input };
const match = regex.exec(input);
if (!match) {
return output;
}
str = str.slice(open.length);
const len = str.length;
let closeIdx = str.indexOf(close);
if (closeIdx === -1) {
closeIdx = len;
}
// get the raw front-matter block
output.matter = str.slice(0, closeIdx);
output.content = str.slice(closeIdx + close.length);
output.matter = match[1];
output.content = input.slice(match[0].length);
const loaded = load(output.matter);
output.data = loaded ?? {};
+1 -1
View File
@@ -1,7 +1,7 @@
// @ts-nocheck -- skip type checking
import * as _source from "./config"
import { _runtimeAsync, buildConfig } from "fumadocs-mdx/runtime/async"
const [err, _sourceConfig] = buildConfig(_source)
if (!_sourceConfig) throw new Error(err)
import { _runtime } from "fumadocs-mdx"
import * as _source from "./config"
export const docs = _runtimeAsync.doc<typeof _source.docs>([{"info":{"path":"index.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/index.mdx"},"data":{},"content":"# Hello World\n"}, {"info":{"path":"folder/test.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/folder/test.mdx"},"data":{},"content":""}], "docs", _sourceConfig)
+1
View File
@@ -2,4 +2,5 @@
import * as docs_1 from "./folder/test.mdx?collection=docs&hash=hash"
import * as docs_0 from "./index.mdx?collection=docs&hash=hash"
import { _runtime } from "fumadocs-mdx"
import * as _source from "./config"
export const docs = _runtime.doc<typeof _source.docs>([{ info: {"path":"index.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/index.mdx"}, data: docs_0 }, { info: {"path":"folder/test.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/folder/test.mdx"}, data: docs_1 }]);
+47
View File
@@ -5,6 +5,7 @@ import { z } from 'zod';
import { ValidationError } from '@/utils/schema';
import { generateJS } from '@/map/generate';
import { defineCollections } from '@/config';
import { fumaMatter } from '@/utils/fuma-matter';
test('format errors', async () => {
const schema = z.object({
@@ -79,3 +80,49 @@ for (const { name, collection } of cases) {
);
});
}
test('parse frontmatter', () => {
expect(
fumaMatter(
'---\ntitle: hello world\ndescription: I love Fumadocs\n---\nwow looks cool.',
),
).toMatchInlineSnapshot(`
{
"content": "wow looks cool.",
"data": {
"description": "I love Fumadocs",
"title": "hello world",
},
"matter": "title: hello world
description: I love Fumadocs",
}
`);
expect(
fumaMatter(
'---\r\ntitle: hello world\r\ndescription: I love Fumadocs\r\n---\r\nwow looks cool.',
),
).toMatchInlineSnapshot(`
{
"content": "wow looks cool.",
"data": {
"description": "I love Fumadocs",
"title": "hello world",
},
"matter": "title: hello world
description: I love Fumadocs",
}
`);
expect(fumaMatter('--- \ntitle: hello world\r\n---\r\nwow looks cool.'))
.toMatchInlineSnapshot(`
{
"content": "---
title: hello world
---
wow looks cool.",
"data": {},
"matter": "",
}
`);
});