// View shaping for SSR payloads. Pages run API rows through these in // useAsyncData's transform, so the serialized payload carries only what the // page renders: no raw `content` source, no `translations`, and never an HTML // body that failed the Journal gate. import { gateJournalHtml } from './htmlGate.ts' import type { JournalPost, JournalPostDetail } from './types.ts' /** A post row as a list or card renders it: without body, source or translations. */ export function toListPost(post: JournalPost): JournalPost { return { ...post, content: null, content_html: null, translations: null } } /** A post page's data: the gated body, with `content_blocked` set when the gate refused it. */ export interface JournalPostView extends JournalPostDetail { content_blocked: boolean } export function toPostView(post: JournalPostDetail): JournalPostView { const gated = gateJournalHtml(post.content_html) return { ...post, content: null, translations: null, content_html: gated.html, content_blocked: !gated.safe, related_posts: (post.related_posts ?? []).map(toListPost), } }