This commit is contained in:
Cayden Schwechten 2026-10-31 21:20:16 -05:00
commit 6250d23297
53 changed files with 6381 additions and 0 deletions

View file

@ -0,0 +1,45 @@
import type { ProviderId, ProviderInfo, WeatherProvider } from "../types";
import { openMeteo } from "./openmeteo";
import { openWeather } from "./openweather";
import { tomorrowIo } from "./tomorrow";
import { weatherApi } from "./weatherapi";
/**
* The provider registry.
* To add a provider: write an adapter that satisfies WeatherProvider,
* add it here, and add its id to ProviderId in ../types.ts.
*/
export const PROVIDERS: Record<ProviderId, WeatherProvider> = {
openweather: openWeather,
weatherapi: weatherApi,
tomorrow: tomorrowIo,
openmeteo: openMeteo,
};
/** Order shown in the picker. OpenWeather first because it's the default. */
const DISPLAY_ORDER: ProviderId[] = ["openweather", "weatherapi", "tomorrow", "openmeteo"];
export function isProviderId(value: string): value is ProviderId {
return value in PROVIDERS;
}
/** A provider is ready if it needs no key, or its key is present. */
export function isReady(provider: WeatherProvider): boolean {
return provider.envKey === null || Boolean(process.env[provider.envKey]?.trim());
}
/** Provider list for the browser — readiness and limits only, never the keys.
* Ready sources lead so the picker starts with working options out of the box. */
export function listProviders(): ProviderInfo[] {
const all = DISPLAY_ORDER.map((id) => {
const provider = PROVIDERS[id];
return {
id,
label: provider.label,
ready: isReady(provider),
signupUrl: provider.signupUrl,
...provider.limits(),
};
});
return [...all.filter((p) => p.ready), ...all.filter((p) => !p.ready)];
}