// The post page's SSR payload: the post with its body sanitized (h1 demoted // to h2 while the Journal H1 setting is on), without the raw `content` // source or `translations`, and with related posts as list rows. Kept apart from view.ts because it loads the sanitizer, which list // pages and cards do not need. import { sanitizeJournalHtml } from './htmlGate.ts' import type { JournalPostDetail } from './types.ts' import { toListPost } from './view.ts' /** * True while the post's body h1 headings become h2 (the Journal API's * content_h1_to_h2; absent on an older Journal, which counts as on). */ export function demotesH1(post: { content_h1_to_h2?: boolean | null } | null | undefined): boolean { return post?.content_h1_to_h2 !== false } /** * The previous and next links of a post page: the neighbours within the * post's first category when the Journal answers them (its opt-in scored * mode) and at least one exists, else the site-wide previous_post and * next_post. */ export function postNeighbours(post: { previous_post?: { slug: string; title: string } | null next_post?: { slug: string; title: string } | null previous_in_category?: { slug: string; title: string } | null next_in_category?: { slug: string; title: string } | null }): { previous: { slug: string; title: string } | null; next: { slug: string; title: string } | null; inCategory: boolean } { if (post.previous_in_category || post.next_in_category) { return { previous: post.previous_in_category ?? null, next: post.next_in_category ?? null, inCategory: true } } return { previous: post.previous_post ?? null, next: post.next_post ?? null, inCategory: false } } /** A post page's data: the post with its body sanitized and no source or translations. */ export type JournalPostView = JournalPostDetail export function toPostView(post: JournalPostDetail): JournalPostView { return { ...post, content: null, translations: null, content_html: sanitizeJournalHtml(post.content_html, { demoteH1: demotesH1(post) }), related_posts: (post.related_posts ?? []).map(toListPost), } }