mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-02 10:10:28 +08:00
Don't throw on empty or invalid frontmatter
Since js-yaml 5 an empty or comment-only block throws instead of returning undefined, as does invalid YAML. Markdown renders the content from the same parse, so one such block made the whole document fail to render.
This commit is contained in:
@@ -12,7 +12,12 @@ export function parseFrontmatter(input: string): ParsedFrontmatter {
|
||||
if (!match) {
|
||||
return { data: {}, content: input };
|
||||
}
|
||||
const parsed = load(match[1]);
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = load(match[1]);
|
||||
} catch {
|
||||
parsed = undefined;
|
||||
}
|
||||
const data =
|
||||
parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
||||
? (parsed as Record<string, unknown>)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { parseFrontmatter } from "@app/lib/frontmatter";
|
||||
|
||||
test.each([
|
||||
["LF", "---\ntitle: Hello\nn: 1\n---\n# Body\n"],
|
||||
["CRLF", "---\r\ntitle: Hello\r\nn: 1\r\n---\r\n# Body\n"],
|
||||
])("splits %s frontmatter from the content", (_, input) => {
|
||||
expect(parseFrontmatter(input)).toEqual({
|
||||
data: { title: "Hello", n: 1 },
|
||||
content: "# Body\n",
|
||||
});
|
||||
});
|
||||
|
||||
test("accepts a closing fence at the end of the input", () => {
|
||||
expect(parseFrontmatter("---\na: 1\n---")).toEqual({
|
||||
data: { a: 1 },
|
||||
content: "",
|
||||
});
|
||||
});
|
||||
|
||||
test("stops at the first closing fence", () => {
|
||||
expect(parseFrontmatter("---\na: 1\n---\ntext\n---\nmore")).toEqual({
|
||||
data: { a: 1 },
|
||||
content: "text\n---\nmore",
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
"# Title\n---\na: 1\n---\n",
|
||||
" ---\na: 1\n---\n",
|
||||
"---\na: 1\n",
|
||||
"---\n---\n",
|
||||
])("leaves %j without frontmatter as is", input => {
|
||||
expect(parseFrontmatter(input)).toEqual({ data: {}, content: input });
|
||||
});
|
||||
|
||||
test.each([
|
||||
["a scalar", "just text"],
|
||||
["a list", "- a\n- b"],
|
||||
["null", "~"],
|
||||
["nothing", ""],
|
||||
["a comment", "# draft"],
|
||||
["invalid YAML", "Note: see: below"],
|
||||
])("drops a block holding %s but strips it", (_, yaml) => {
|
||||
expect(parseFrontmatter(`---\n${yaml}\n---\nbody`)).toEqual({
|
||||
data: {},
|
||||
content: "body",
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user