/* RFC-0167: builds the Article/BlogPosting JSON-LD node from a page that carries article metadata (datePublished/author/…). Gives Google freshness/Discover signals and LLM recency + attribution that a bare WebPage lacks. Do not emit when the page has no datePublished. RFC-0167: initial implementation. */ import type { JsonLdContext } from "./context.ts"; import type { JsonLdNode } from "./types.ts"; export function buildArticleNode(context: JsonLdContext): JsonLdNode | null { const { page, ids, webpageId } = context; if (!page.datePublished) { return null; } const isRatgeberDepth1 = page.surfaceId === "ratgeber" && page.depth === 1; const author = page.authorRecord ? { "@type": "Person", name: page.authorRecord.name, ...(page.authorRecord.contactUrl ? { url: page.authorRecord.contactUrl } : {}), } : page.author ? { "@type": "Person", name: page.author } : undefined; return { "@type": ["Article", "BlogPosting"], "@id": webpageId.replace("#/schema/webpage", "#/schema/article"), headline: page.heading ?? page.title, description: page.description, datePublished: page.datePublished, dateModified: page.dateModified ?? page.datePublished, ...(author ? { author } : {}), publisher: { "@id": ids.organization }, mainEntityOfPage: isRatgeberDepth1 ? page.url : { "@id": webpageId }, inLanguage: page.lang, ...(page.primaryImage ? { image: page.primaryImage.url } : {}), ...(page.keywords?.length ? { keywords: page.keywords.join(", ") } : {}), }; }