import { zValidator } from '@hono/zod-validator'; import { Hono } from 'hono'; import { ImageResponse } from 'workers-og'; import { z } from 'zod'; import type { HonoEnv } from '../app'; const getBriefOpenGraph = (opts: { title: string; date: Date; totalArticles: number; totalSources: number }) => `
${opts.date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}
Intelligence brief · ${opts.totalArticles} articles · ${opts.totalSources} sources
news.iliane.xyz
${decodeURIComponent(opts.title.trim())}
`; const getHomeOpenGraph = () => `
Meridian
a daily brief of everything important happening that i care about, with actual analysis beyond headlines
`; const route = new Hono() .get('/default', async c => { const response = new ImageResponse(getHomeOpenGraph(), { width: 1200, height: 630 }); response.headers.set('Cache-Control', 'public, max-age=86400'); // Cache for 1 day return response; }) .get( '/brief', zValidator( 'query', z.object({ title: z.string(), date: z.string().transform(val => new Date(Number.parseInt(val))), articles: z.string().transform(val => Number.parseInt(val)), sources: z.string().transform(val => Number.parseInt(val)), }) ), async c => { const query = c.req.valid('query'); const response = new ImageResponse( getBriefOpenGraph({ title: query.title, date: query.date, totalArticles: query.articles, totalSources: query.sources, }), { width: 1200, height: 630 } ); // Cache brief images for longer since they don't change much despite having params response.headers.set('Cache-Control', 'public, max-age=86400, stale-while-revalidate=43200'); return response; } ); export default route;