SPB Git forge

spb/fetcha

Public
11commits 1branches 0releases
1.5 MBsize
maindefault branch
16 days agolast push
TypeScript 97.5% SQL 1.4% Python 0.8%
3.4 KB · 115 lines typescript
Raw Blame History
1/** Fetcha's internal geography model. Providers translate from this. */2export interface GeoTarget {3  country: string | null; // ISO 3166-1 alpha-2, upper-case4  region: string | null; // free-form, normalized lower-case slug (e.g. "quebec", "california")5  city: string | null; // normalized lower-case slug6}78export const COUNTRIES: Record<string, string> = {9  US: "United States",10  CA: "Canada",11  GB: "United Kingdom",12  DE: "Germany",13  FR: "France",14  ES: "Spain",15  IT: "Italy",16  NL: "Netherlands",17  BE: "Belgium",18  CH: "Switzerland",19  AT: "Austria",20  SE: "Sweden",21  NO: "Norway",22  DK: "Denmark",23  FI: "Finland",24  IE: "Ireland",25  PT: "Portugal",26  PL: "Poland",27  CZ: "Czechia",28  AU: "Australia",29  NZ: "New Zealand",30  JP: "Japan",31  KR: "South Korea",32  SG: "Singapore",33  HK: "Hong Kong",34  IN: "India",35  BR: "Brazil",36  MX: "Mexico",37  AR: "Argentina",38  CL: "Chile",39  CO: "Colombia",40  ZA: "South Africa",41  AE: "United Arab Emirates",42  IL: "Israel",43  TR: "Türkiye",44  TW: "Taiwan",45  TH: "Thailand",46  VN: "Vietnam",47  ID: "Indonesia",48  PH: "Philippines",49  MY: "Malaysia",50  GR: "Greece",51  RO: "Romania",52  HU: "Hungary",53  UA: "Ukraine",54};5556const CA_REGIONS: Record<string, string> = {57  qc: "quebec",58  quebec: "quebec",59  québec: "quebec",60  on: "ontario",61  ontario: "ontario",62  bc: "british_columbia",63  "british columbia": "british_columbia",64  ab: "alberta",65  alberta: "alberta",66  mb: "manitoba",67  manitoba: "manitoba",68  sk: "saskatchewan",69  saskatchewan: "saskatchewan",70  ns: "nova_scotia",71  "nova scotia": "nova_scotia",72  nb: "new_brunswick",73  "new brunswick": "new_brunswick",74  nl: "newfoundland_and_labrador",75  pe: "prince_edward_island",76  pei: "prince_edward_island",77  yt: "yukon",78  nt: "northwest_territories",79  nu: "nunavut",80};8182const US_STATES: Record<string, string> = {83  al: "alabama", ak: "alaska", az: "arizona", ar: "arkansas", ca: "california", co: "colorado", ct: "connecticut",84  de: "delaware", fl: "florida", ga: "georgia", hi: "hawaii", id: "idaho", il: "illinois", in: "indiana", ia: "iowa",85  ks: "kansas", ky: "kentucky", la: "louisiana", me: "maine", md: "maryland", ma: "massachusetts", mi: "michigan",86  mn: "minnesota", ms: "mississippi", mo: "missouri", mt: "montana", ne: "nebraska", nv: "nevada", nh: "new_hampshire",87  nj: "new_jersey", nm: "new_mexico", ny: "new_york", nc: "north_carolina", nd: "north_dakota", oh: "ohio", ok: "oklahoma",88  or: "oregon", pa: "pennsylvania", ri: "rhode_island", sc: "south_carolina", sd: "south_dakota", tn: "tennessee",89  tx: "texas", ut: "utah", vt: "vermont", va: "virginia", wa: "washington", wv: "west_virginia", wi: "wisconsin", wy: "wyoming",90  dc: "district_of_columbia",91};9293export function slugifyGeo(s: string): string {94  return s95    .normalize("NFD")96    .replace(/[̀-ͯ]/g, "")97    .toLowerCase()98    .trim()99    .replace(/[^a-z0-9]+/g, "_")100    .replace(/^_+|_+$/g, "");101}102103export function normalizeGeo(input: { country?: string | null; region?: string | null; city?: string | null }): GeoTarget {104  const country = input.country ? input.country.toUpperCase() : null;105  let region: string | null = null;106  if (input.region) {107    const key = input.region.toLowerCase().trim();108    if (country === "CA" && CA_REGIONS[key]) region = CA_REGIONS[key]!;109    else if (country === "US" && US_STATES[key]) region = US_STATES[key]!;110    else region = slugifyGeo(input.region);111  }112  const city = input.city ? slugifyGeo(input.city) : null;113  return { country, region, city };114}115