From 252bbc6effc9f3f5a4c6a8472c77fca43ba10980 Mon Sep 17 00:00:00 2001 From: Heath Stewart Date: Wed, 03 Jun 2026 06:38:50 +0000 Subject: [PATCH] Always atUri to frontmatter root Fixes #46 --- packages/cli/test/markdown.test.ts | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ packages/cli/src/lib/markdown.ts | 26 ++++++-------------------- 2 file(s) changed, 125 insertion(s)(+), 20 deletion(s)(-) diff --git a/packages/cli/test/markdown.test.ts b/packages/cli/test/markdown.test.ts --- a/packages/cli/test/markdown.test.ts +++ b/packages/cli/test/markdown.test.ts @@ -4,6 +4,7 @@ parseFrontmatter, resolvePostPath, stripMarkdownForText, + updateFrontmatterWithAtUri, } from "../src/lib/markdown"; import type { BlogPost } from "../src/lib/types"; import type { BlobOptions } from "node:buffer"; @@ -390,6 +391,27 @@ const { body } = parseFrontmatter(content); expect(body).toBe(""); }); + + it("preserves TOML tables", () => { + const content = `+++ +title = "Example" +coverImage = "static/covers/example.png" + +[cover] + image = "/covers/example.png" + alt = "…" + hidden = true ++++ +Body content here.`; + const { frontmatter, body, rawFrontmatter } = parseFrontmatter(content); + expect(frontmatter.title).toBe("Example"); + expect(body).toBe("Body content here."); + + const coverTable = rawFrontmatter?.["cover"] as Record | undefined; + expect(coverTable).not.toBe(undefined); + const coverImageField = coverTable?.["image"] as string | undefined; + expect(coverImageField).toBe("/covers/example.png"); + }); }); }); @@ -492,6 +514,103 @@ it("trims leading and trailing whitespace", () => { expect(stripMarkdownForText("\n\nhello\n\n")).toBe("hello"); + }); +}); + +describe("updateFrontmatterWithAtUri", () => { + it("inserts atUri into YAML frontmatter when it does not exist", () => { + const content = `--- +title: Hello World +--- +Body content here.`; + const updatedContent = updateFrontmatterWithAtUri( + content, + "at://did:plc:abc123/app.bsky.feed.post/xyz", + ); + + expect(updatedContent).toBe(`--- +title: Hello World +atUri: at://did:plc:abc123/app.bsky.feed.post/xyz +--- +Body content here.`); + }); + + it("replaces an existing atUri in YAML frontmatter", () => { + const content = `--- +title: Hello World +atUri: "at://did:plc:old/app.bsky.feed.post/old" +--- +Body content here.`; + const updatedContent = updateFrontmatterWithAtUri( + content, + "at://did:plc:new/app.bsky.feed.post/new", + ); + + expect(updatedContent).toBe(`--- +title: Hello World +atUri: at://did:plc:new/app.bsky.feed.post/new +--- +Body content here.`); + }); + + it("inserts atUri into TOML frontmatter when it does not exist", () => { + const content = `+++ +title = "Hello World" ++++ +Body content here.`; + const updatedContent = updateFrontmatterWithAtUri( + content, + "at://did:plc:abc123/app.bsky.feed.post/xyz", + ); + + expect(updatedContent).toBe(`+++ +title = "Hello World" +atUri = "at://did:plc:abc123/app.bsky.feed.post/xyz" ++++ +Body content here.`); + }); + + it("replaces an existing atUri in TOML frontmatter", () => { + const content = `+++ +title = "Hello World" +atUri = "at://did:plc:old/app.bsky.feed.post/old" ++++ +Body content here.`; + const updatedContent = updateFrontmatterWithAtUri( + content, + "at://did:plc:new/app.bsky.feed.post/new", + ); + + expect(updatedContent).toBe(`+++ +title = "Hello World" +atUri = "at://did:plc:new/app.bsky.feed.post/new" ++++ +Body content here.`); + }); + + it("inserts atUri into TOML frontmatter when it include another table", () => { + const content = `+++ +title = "Example" +coverImage = "static/covers/example.png" + +[cover] + image = "/covers/example.png" + alt = "…" + hidden = true ++++ +Body content here.`; + const updatedContent = updateFrontmatterWithAtUri(content, "at://did:plc:new/app.bsky.feed.post/new"); + expect(updatedContent).toBe(`+++ +title = "Example" +coverImage = "static/covers/example.png" +atUri = "at://did:plc:new/app.bsky.feed.post/new" + +[cover] +image = "/covers/example.png" +alt = "…" +hidden = true ++++ +Body content here.`); }); }); diff --git a/packages/cli/src/lib/markdown.ts b/packages/cli/src/lib/markdown.ts --- a/packages/cli/src/lib/markdown.ts +++ b/packages/cli/src/lib/markdown.ts @@ -376,29 +376,15 @@ const delimiterMatch = rawContent.match(/^(---|\+\+\+|\*\*\*)/); const delimiter = delimiterMatch?.[1] ?? "---"; const isToml = delimiter === "+++"; + const { body, rawFrontmatter } = parseFrontmatter(rawContent); - // Format the atUri entry based on frontmatter type - const atUriEntry = isToml ? `atUri = "${atUri}"` : `atUri: "${atUri}"`; + rawFrontmatter.atUri = atUri; - // Check if atUri already exists in frontmatter (handle both formats) - if (rawContent.includes("atUri:") || rawContent.includes("atUri =")) { - // Replace existing atUri (match both YAML and TOML formats) - return rawContent.replace( - /atUri\s*[=:]\s*["']?[^"'\n]+["']?\n?/, - `${atUriEntry}\n`, - ); - } + const serializedFrontmatter = isToml + ? toml.stringify(rawFrontmatter).trimEnd() + : yaml.dump(rawFrontmatter, { lineWidth: -1 }).trimEnd(); - // Insert atUri before the closing delimiter - const frontmatterEndIndex = rawContent.indexOf(delimiter, 4); - if (frontmatterEndIndex === -1) { - throw new Error("Could not find frontmatter end"); - } - - const beforeEnd = rawContent.slice(0, frontmatterEndIndex); - const afterEnd = rawContent.slice(frontmatterEndIndex); - - return `${beforeEnd}${atUriEntry}\n${afterEnd}`; + return `${delimiter}\n${serializedFrontmatter}\n${delimiter}\n${body}`; } export function stripMarkdownForText(markdown: string): string { -- tangled.sh