the best ios gas tracking app
at main 75 lines 2.1 kB view raw
1// EIA duoarea code -> 2-letter state abbreviation 2const DUOAREA_TO_STATE: Record<string, string> = { 3 SAK: "AK", SAL: "AL", SAR: "AR", SAZ: "AZ", SCA: "CA", 4 SCO: "CO", SCT: "CT", SDC: "DC", SDE: "DE", SFL: "FL", 5 SGA: "GA", SHI: "HI", SIA: "IA", SID: "ID", SIL: "IL", 6 SIN: "IN", SKS: "KS", SKY: "KY", SLA: "LA", SMA: "MA", 7 SMD: "MD", SME: "ME", SMI: "MI", SMN: "MN", SMO: "MO", 8 SMS: "MS", SMT: "MT", SNC: "NC", SND: "ND", SNE: "NE", 9 SNH: "NH", SNJ: "NJ", SNM: "NM", SNV: "NV", SNY: "NY", 10 SOH: "OH", SOK: "OK", SOR: "OR", SPA: "PA", SRI: "RI", 11 SSC: "SC", SSD: "SD", STN: "TN", STX: "TX", SUT: "UT", 12 SVA: "VA", SVT: "VT", SWA: "WA", SWI: "WI", SWV: "WV", 13 SWY: "WY", 14}; 15 16export interface StateAverage { 17 state: string; 18 regular: number | null; 19 period: string; // ISO date string of the week 20} 21 22interface EIADataRow { 23 period: string; 24 duoarea: string; 25 product: string; 26 value: number | null; 27} 28 29interface EIAResponse { 30 response: { 31 data: EIADataRow[]; 32 }; 33} 34 35export async function fetchStateAverages(): Promise<StateAverage[]> { 36 const apiKey = process.env.EIA_API_KEY; 37 if (!apiKey) throw new Error("EIA_API_KEY not set"); 38 39 const params = new URLSearchParams({ 40 api_key: apiKey, 41 frequency: "weekly", 42 "data[]": "value", 43 "facets[product][]": "EPM0", // regular unleaded 44 "sort[0][column]": "period", 45 "sort[0][direction]": "desc", 46 length: "60", 47 }); 48 49 const res = await fetch( 50 `https://api.eia.gov/v2/petroleum/pri/gnd/data/?${params}`, 51 ); 52 if (!res.ok) { 53 throw new Error(`EIA API returned ${res.status}`); 54 } 55 56 const json = (await res.json()) as EIAResponse; 57 const rows = json.response.data; 58 59 // Keep only the most recent entry per state 60 const latestByState = new Map<string, EIADataRow>(); 61 for (const row of rows) { 62 const state = DUOAREA_TO_STATE[row.duoarea]; 63 if (!state) continue; 64 const existing = latestByState.get(state); 65 if (!existing || row.period > existing.period) { 66 latestByState.set(state, row); 67 } 68 } 69 70 return Array.from(latestByState.entries()).map(([state, row]) => ({ 71 state, 72 regular: row.value, 73 period: row.period, 74 })); 75}