import type { RequestHandler } from './$types'; import { json } from '@sveltejs/kit'; import { getPages, getPosts } from '$lib/cms'; import { filterHiddenPosts, sortPostsByDate, getPostImageUrl, postHref, } from '$lib/blog-utils'; import { ensureTransformedImage } from '$lib/rusty-image'; export type SearchHit = { type: 'page' | 'post'; slug: string; href: string; title: string; subtitle: string; excerpt: string; image: string | null; created: string | null; isEvent?: boolean; eventDate?: string | null; }; function pageHref(p: { slug?: string; _slug?: string }): string { const raw = (p.slug ?? p._slug ?? '').replace(/^\//, '').trim(); if (!raw || raw === 'home') return '/'; return '/' + raw.split('/').filter(Boolean).map(encodeURIComponent).join('/') + '/'; } export const GET: RequestHandler = async () => { let pages: Awaited> = []; let posts: Awaited> = []; try { [pages, posts] = await Promise.all([ getPages(), getPosts({ resolve: ['postImage'] }), ]); } catch { return json({ hits: [] satisfies SearchHit[] }); } posts = filterHiddenPosts(sortPostsByDate(posts)); const postHits: SearchHit[] = await Promise.all( posts.map(async (p) => { const raw = getPostImageUrl(p.postImage); let image: string | null = null; if (raw) { try { image = await ensureTransformedImage(raw, { width: 160, height: 106, fit: 'cover', format: 'webp', }); } catch { /* optional */ } } return { type: 'post', slug: p.slug ?? p._slug ?? '', href: postHref(p), title: p.headline ?? p.linkName ?? p._slug ?? '', subtitle: p.subheadline ?? '', excerpt: p.excerpt ?? '', image, created: p.created ?? null, isEvent: Boolean((p as { isEvent?: boolean }).isEvent), eventDate: (p as { eventDate?: string }).eventDate ?? null, }; }), ); const pageHits: SearchHit[] = pages .filter((p) => !(p as { hideFromSearch?: boolean }).hideFromSearch) .map((p) => ({ type: 'page', slug: p.slug ?? p._slug ?? '', href: pageHref(p), title: (p as { headline?: string }).headline ?? (p as { title?: string }).title ?? p._slug ?? '', subtitle: (p as { subheadline?: string }).subheadline ?? '', excerpt: (p as { excerpt?: string }).excerpt ?? '', image: null, created: (p as { created?: string }).created ?? null, })); return json( { hits: [...pageHits, ...postHits] satisfies SearchHit[] }, { headers: { 'cache-control': 'public, max-age=60, s-maxage=60' } }, ); };