/** * Service for fetching NASA FIRMS (Fire Information for Resource Management * System) satellite fire-detection data — VIIRS near-real-time hotspots. * * Two ingestion paths (see `docs/plans/global-wildfire-plan.md` D3/D4): * * - **Keyed Area API** (`getDetectionsByBbox`): targeted bbox query, * `day_range` 1-5, requires `FIRMS_MAP_KEY`. The map key is embedded in * the request URL itself — see the security note below. * - **Keyless flat files** (`getDetectionsByRegion`): fixed 24 h regional * CSV cuts, no key required, no key in the URL. * * Both paths return the same normalized `FIRMSDetection[]` via * `parseFIRMSCsv` (`src/utils/firmsHotspots.ts`) — CSV parsing, region * selection, and clustering are pure functions that live there; this module * is purely I/O (fetch + cache + error mapping), mirroring the * `nifc.ts`/`metarStation.ts` split. * * **Security: the MAP_KEY lives in the URL.** Error mapping below never * logs or throws the request URL, and never interpolates the raw axios * error message/object into a thrown message — every thrown error is a * fixed, pre-written string (the `nifc.ts` `queryFeatureServer` mapping * style), so the key can never leak through a log line or an error surfaced * to a caller. Coordinates in log metadata go through * `redactCoordinatesForLogging`. */ import type { FIRMSDetection, FIRMSRegionFile } from '../types/firms.js'; /** * Thrown when the FIRMS Area API rejects the configured `FIRMS_MAP_KEY` * (HTTP 400/401 with `Invalid MAP_KEY` in the response body). Deliberately * carries a fixed, sanitized message — never the key or the request URL — * so callers (the wildfire handler) can catch this specific case and fall * back to the keyless path with a disclosure note (D3), without ever * touching the rejected key again. */ export declare class FIRMSKeyRejectedError extends Error { constructor(); } export interface FIRMSServiceConfig { timeout?: number; /** Overrides the `FIRMS_MAP_KEY` env var — primarily for tests. */ mapKey?: string; } export declare class FIRMSService { private client; private cache; private readonly mapKey; constructor(config?: FIRMSServiceConfig); /** * Get cache statistics */ getCacheStats(): import("../utils/cache.js").CacheStats; /** * Clear the cache */ clearCache(): void; /** * True when a non-empty FIRMS map key is configured. */ isKeyAvailable(): boolean; /** * Keyed Area API — targeted bbox query, `dayRange` days of detections. * * @throws {FIRMSKeyRejectedError} the configured key was rejected * @throws {Error} no key configured, invalid bbox, or any other failure */ getDetectionsByBbox(west: number, south: number, east: number, north: number, dayRange: number): Promise; private queryAreaApi; /** * Keyless flat-file path — the fixed 24 h regional cut (or `Global`), * parsed and cached whole. */ getDetectionsByRegion(regionFile: FIRMSRegionFile): Promise; private fetchRegionFile; } //# sourceMappingURL=firms.d.ts.map