/** * Helper for fetching comment counts in bulk and keying them by post slug. * Used by overview components (BlogOverview, PostOverviewBlock) so each * render fires a single `/api/comments/counts?ids=…` request instead of * one request per card. */ import { env } from "$env/dynamic/public"; import type { PostEntry } from "$lib/cms"; export type CommentCountsMap = Record; /** Strip the leading slash so it matches `params.slug` (= comment page_id). */ export function postSlugForComments(p: PostEntry): string { const raw = (p as { slug?: string; _slug?: string }).slug ?? p._slug ?? ""; return raw.replace(/^\//, "").trim(); } /** * Bulk-fetch approved comment counts for many posts. Returns a map * `{ slug: count }` (slug as in `postSlugForComments`). Missing or failed * responses resolve to an empty object — callers can then `?? null` per slug. */ export async function fetchCommentCounts( slugs: string[], options?: { environment?: string; signal?: AbortSignal }, ): Promise { const cleaned = slugs.filter(Boolean); if (cleaned.length === 0) return {}; const cmsBase = ( env.PUBLIC_CMS_URL || import.meta.env.PUBLIC_CMS_URL || "" ).replace(/\/$/, ""); if (!cmsBase) return {}; const url = new URL(`${cmsBase}/api/comments/counts`); url.searchParams.set("ids", cleaned.join(",")); if (options?.environment) { url.searchParams.set("_environment", options.environment); } try { const r = await fetch(url.toString(), { signal: options?.signal }); if (!r.ok) return {}; const d = (await r.json()) as { counts?: CommentCountsMap }; return d?.counts ?? {}; } catch { return {}; } }