/** Fetcha's internal geography model. Providers translate from this. */ export interface GeoTarget { country: string | null; // ISO 3166-1 alpha-2, upper-case region: string | null; // free-form, normalized lower-case slug (e.g. "quebec", "california") city: string | null; // normalized lower-case slug } export const COUNTRIES: Record = { US: "United States", CA: "Canada", GB: "United Kingdom", DE: "Germany", FR: "France", ES: "Spain", IT: "Italy", NL: "Netherlands", BE: "Belgium", CH: "Switzerland", AT: "Austria", SE: "Sweden", NO: "Norway", DK: "Denmark", FI: "Finland", IE: "Ireland", PT: "Portugal", PL: "Poland", CZ: "Czechia", AU: "Australia", NZ: "New Zealand", JP: "Japan", KR: "South Korea", SG: "Singapore", HK: "Hong Kong", IN: "India", BR: "Brazil", MX: "Mexico", AR: "Argentina", CL: "Chile", CO: "Colombia", ZA: "South Africa", AE: "United Arab Emirates", IL: "Israel", TR: "Türkiye", TW: "Taiwan", TH: "Thailand", VN: "Vietnam", ID: "Indonesia", PH: "Philippines", MY: "Malaysia", GR: "Greece", RO: "Romania", HU: "Hungary", UA: "Ukraine", }; const CA_REGIONS: Record = { qc: "quebec", quebec: "quebec", québec: "quebec", on: "ontario", ontario: "ontario", bc: "british_columbia", "british columbia": "british_columbia", ab: "alberta", alberta: "alberta", mb: "manitoba", manitoba: "manitoba", sk: "saskatchewan", saskatchewan: "saskatchewan", ns: "nova_scotia", "nova scotia": "nova_scotia", nb: "new_brunswick", "new brunswick": "new_brunswick", nl: "newfoundland_and_labrador", pe: "prince_edward_island", pei: "prince_edward_island", yt: "yukon", nt: "northwest_territories", nu: "nunavut", }; const US_STATES: Record = { al: "alabama", ak: "alaska", az: "arizona", ar: "arkansas", ca: "california", co: "colorado", ct: "connecticut", de: "delaware", fl: "florida", ga: "georgia", hi: "hawaii", id: "idaho", il: "illinois", in: "indiana", ia: "iowa", ks: "kansas", ky: "kentucky", la: "louisiana", me: "maine", md: "maryland", ma: "massachusetts", mi: "michigan", mn: "minnesota", ms: "mississippi", mo: "missouri", mt: "montana", ne: "nebraska", nv: "nevada", nh: "new_hampshire", nj: "new_jersey", nm: "new_mexico", ny: "new_york", nc: "north_carolina", nd: "north_dakota", oh: "ohio", ok: "oklahoma", or: "oregon", pa: "pennsylvania", ri: "rhode_island", sc: "south_carolina", sd: "south_dakota", tn: "tennessee", tx: "texas", ut: "utah", vt: "vermont", va: "virginia", wa: "washington", wv: "west_virginia", wi: "wisconsin", wy: "wyoming", dc: "district_of_columbia", }; export function slugifyGeo(s: string): string { return s .normalize("NFD") .replace(/[̀-ͯ]/g, "") .toLowerCase() .trim() .replace(/[^a-z0-9]+/g, "_") .replace(/^_+|_+$/g, ""); } export function normalizeGeo(input: { country?: string | null; region?: string | null; city?: string | null }): GeoTarget { const country = input.country ? input.country.toUpperCase() : null; let region: string | null = null; if (input.region) { const key = input.region.toLowerCase().trim(); if (country === "CA" && CA_REGIONS[key]) region = CA_REGIONS[key]!; else if (country === "US" && US_STATES[key]) region = US_STATES[key]!; else region = slugifyGeo(input.region); } const city = input.city ? slugifyGeo(input.city) : null; return { country, region, city }; }