import { z } from "zod";
export const temperatureUnitSchema = z.enum(["celsius", "fahrenheit"]);
export type TemperatureUnit = z.infer<typeof temperatureUnitSchema>;
interface GeocodingResult {
latitude: number;
longitude: number;
name: string;
country: string;
}
interface CurrentWeather {
temperature: number;
humidity: number;
weatherCode: number;
windSpeed: number;
city: string;
country: string;
unit: TemperatureUnit;
}
interface ForecastDay {
date: string;
maxTemp: number;
minTemp: number;
weatherCode: number;
}
interface Forecast {
city: string;
country: string;
unit: TemperatureUnit;
days: ForecastDay[];
}
// Convert city name to coordinates
export async function getCoordinates(city: string): Promise<GeocodingResult> {
const url = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1`;
const response = await fetch(url);
const data = await response.json();
if (!data.results || data.results.length === 0) {
throw new Error(`City not found: ${city}`);
}
const results = data.results[0];
return {
latitude: results.latitude,
longitude: results.longitude,
name: results.name,
country: results.country
};
}
// Get current weather for a city
export async function getCurrentWeather(city:string,unit:TemperatureUnit="celsius"): Promise<CurrentWeather>{
const location = await getCoordinates(city);
const url = `https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}¤t=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m&temperature_unit=${unit}`;
const response = await fetch(url);
const data = await response.json();
return {
temperature:data.current.temperature_2m,
humidity:data.current.relative_humidity_2m,
weatherCode:data.current.weather_code,
windSpeed: data.current.wind_speed_10m,
city: location.name,
country: location.country,
unit,
};
}
// Get weather forecast for a city
export async function getForecast(
city: string,
days: number = 3,
unit: TemperatureUnit = "celsius"
): Promise<Forecast> {
const location = await getCoordinates(city);
const url = `https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}&daily=temperature_2m_max,temperature_2m_min,weather_code&forecast_days=${days}&temperature_unit=${unit}`;
const response = await fetch(url);
const data = await response.json();
const forecastDays: ForecastDay[] = data.daily.time.map((date: string, i: number) => ({
date,
maxTemp: data.daily.temperature_2m_max[i],
minTemp: data.daily.temperature_2m_min[i],
weatherCode: data.daily.weather_code[i],
}));
return {
city: location.name,
country: location.country,
unit,
days: forecastDays,
};
}