import { z } from "zod"; import { locationSuggestionSchema, type LocationSuggestion } from "@album/contracts"; const photonSchema = z.object({ features: z.array(z.object({ geometry: z.object({ coordinates: z.tuple([z.number(), z.number()]) }), properties: z.record(z.unknown()), })), }); export function parseLocationResults(payload: unknown): LocationSuggestion[] { const parsed = photonSchema.parse(payload); const seen = new Set(); return parsed.features.flatMap(({ geometry, properties }) => { const text = (key: string) => typeof properties[key] === "string" ? properties[key] as string : ""; const street = [text("housenumber"), text("street")].filter(Boolean).join(" "); const address = [...new Set([ text("name"), street, text("city") || text("district") || text("county"), text("state"), text("postcode"), text("country"), ].filter(Boolean))].join(", "); const result = locationSuggestionSchema.safeParse({ address, longitude: geometry.coordinates[0], latitude: geometry.coordinates[1], }); const key = `${address}:${geometry.coordinates.join(",")}`; if (!address || !result.success || seen.has(key)) return []; seen.add(key); return [result.data]; }); } export async function searchLocations(query: string) { const url = new URL("https://photon.komoot.io/api/"); url.searchParams.set("q", query); url.searchParams.set("limit", "6"); url.searchParams.set("lang", "en"); const response = await fetch(url, { headers: { Accept: "application/json", "User-Agent": "Manyangles event location search" }, next: { revalidate: 86_400 }, signal: AbortSignal.timeout(8000), }); if (!response.ok) throw new Error("Location search unavailable"); return parseLocationResults(await response.json()); }