import { packageContext } from 'kody:runtime'
import { getPollen } from './getPollen'
function appUrl(path: string): URL {
if (!packageContext?.hostedUrl) {
throw new Error('This module must run as a package app.')
}
const relative = path.replace(/^\/+/, '')
const mount = packageContext.appBasePath.endsWith('/')
? packageContext.appBasePath
: `${packageContext.appBasePath}/`
return new URL(`${mount}${relative}`, packageContext.hostedUrl)
}
function renderPage(): Response {
const apiPath = appUrl('api/getPollen').pathname
const html = `
Pollen levels
Pollen levels
City name → Open-Meteo pollen grains/m³ (Europe coverage; elsewhere often unavailable).
—
Not medical advice. Data: Open-Meteo / CAMS.
`
return new Response(html, {
headers: {
'content-type': 'text/html; charset=utf-8',
'cache-control': 'no-store',
},
})
}
async function handleApi(request: Request): Promise {
if (request.method !== 'POST') {
return Response.json({ error: 'POST required' }, { status: 405 })
}
let body: {
location?: string
latitude?: number
longitude?: number
hours?: number
} = {}
try {
body = (await request.json()) as typeof body
} catch {
return Response.json({ error: 'Invalid JSON body' }, { status: 400 })
}
try {
const result = await getPollen(body)
return Response.json(result)
} catch (e) {
return Response.json(
{ error: e instanceof Error ? e.message : String(e) },
{ status: 400 },
)
}
}
export default {
async fetch(request: Request): Promise {
const path = new URL(request.url).pathname
if (path === '/' || path === '') return renderPage()
if (path === '/api/getPollen') return handleApi(request)
return new Response('Not found', { status: 404 })
},
}