fix: quote YAML-special and numeric frontmatter values

formatValue now detects YAML-special tokens (true/false/null/yes/no/on/off/y/n/~)
and numeric-looking strings, quoting them via JSON.stringify so YAML parsers
cannot misread them as booleans or numbers. ISO date strings (YYYY-MM-DD) are
exempt and remain bare for readability. Adds four covering tests.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-19 01:49:33 +00:00
parent f2edd9b0ab
commit c24a7e2a11
2 changed files with 14 additions and 0 deletions

View File

@@ -51,4 +51,14 @@ describe("serializeFrontmatter", () => {
test("empty value becomes quoted empty string", () => {
expect(serializeFrontmatter([{ key: "tags", value: "" }])).toBe(`---\ntags: ""\n---\n`);
});
test("YAML-special boolean strings are quoted", () => {
expect(serializeFrontmatter([{ key: "draft", value: "true" }])).toBe(`---\ndraft: "true"\n---\n`);
expect(serializeFrontmatter([{ key: "published", value: "false" }])).toBe(`---\npublished: "false"\n---\n`);
});
test("numeric-looking strings are quoted", () => {
expect(serializeFrontmatter([{ key: "n", value: "42" }])).toBe(`---\nn: "42"\n---\n`);
});
test("ISO date strings remain bare (not quoted as numeric)", () => {
expect(serializeFrontmatter([{ key: "date", value: "2026-06-11" }])).toBe(`---\ndate: 2026-06-11\n---\n`);
});
});

View File

@@ -47,6 +47,10 @@ export function serializeFrontmatter(pairs: Pair[]): string {
function formatValue(v: string): string {
if (v === "") return '""';
const yamlSpecial = /^(true|false|null|yes|no|on|off|y|n|~)$/i.test(v);
const isoDate = /^\d{4}-\d{2}-\d{2}$/.test(v);
const numericLike = !isoDate && /^[+-]?(\d|\.\d)/.test(v);
if (yamlSpecial || numericLike) return JSON.stringify(v);
const bareSafe = /^[A-Za-z0-9_./-][A-Za-z0-9_./ -]*$/.test(v) && !/^\s|\s$/.test(v);
return bareSafe ? v : JSON.stringify(v);
}