import type { APIRoute } from "astro"; import { getCollection } from "astro:content"; import { i18n, roots } from "../config.mjs"; import { withBase } from "../lib/base"; import { decode, routeFor } from "../lib/i18n-content.mjs"; import { isPublicPage, visibleRoots } from "../lib/public-filter"; /** Markdown → texte brut approximatif (pour l'index de recherche). */ function strip(md: string): string { return md .replace(/```[\s\S]*?```/g, " ") .replace(/`[^`]*`/g, " ") .replace(/!\[[^\]]*\]\([^)]*\)/g, " ") .replace(/\[([^\]]*)\]\([^)]*\)/g, "$1") .replace(/^[#>|]+/gm, " ") .replace(/[*_~]/g, " ") .replace(/\s+/g, " ") .trim(); } export const GET: APIRoute = async () => { const out: { space: string; locale: string; href: string; title: string; headings: string[]; text: string; }[] = []; for (const root of visibleRoots(roots)) { const space = root.key; // Dynamic collection (name = space key) → assert the entry shape we read. const entries = (await getCollection(space as never)) as unknown as Array<{ id: string; body?: string; data?: Record; }>; for (const entry of entries) { const body = entry.body ?? ""; const { locale, id } = decode(entry.id, i18n); if (!isPublicPage(space, id, entry.data)) continue; // public-build scoping (no-op otherwise) const fmTitle = typeof entry.data?.title === "string" && entry.data.title.trim() ? entry.data.title.trim() : ""; const titleMatch = body.match(/^#\s+(.+?)\s*$/m); const headings = [...body.matchAll(/^#{2,4}\s+(.+?)\s*$/gm)].map((m) => m[1].replace(/[*_`]/g, "").trim()); out.push({ space, locale, href: withBase(routeFor({ space, id, locale }, i18n)), title: fmTitle || (titleMatch ? titleMatch[1].replace(/[*_`]/g, "").trim() : id), headings, // DEV serves the FULL text: it feeds the Pagefind dev indexer (and the JSON // fallback fetches over loopback). Builds keep the cap — a browser-download // payload for the naive engine. text: import.meta.env.DEV ? strip(body) : strip(body).slice(0, 1500), }); } } return new Response(JSON.stringify(out), { headers: { "content-type": "application/json; charset=utf-8" }, }); };