@jablum/weather-mcp 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1319 -0
- package/dist/analytics/anonymizer.d.ts +37 -0
- package/dist/analytics/anonymizer.d.ts.map +1 -0
- package/dist/analytics/anonymizer.js +112 -0
- package/dist/analytics/anonymizer.js.map +1 -0
- package/dist/analytics/collector.d.ts +72 -0
- package/dist/analytics/collector.d.ts.map +1 -0
- package/dist/analytics/collector.js +282 -0
- package/dist/analytics/collector.js.map +1 -0
- package/dist/analytics/config.d.ts +15 -0
- package/dist/analytics/config.d.ts.map +1 -0
- package/dist/analytics/config.js +172 -0
- package/dist/analytics/config.js.map +1 -0
- package/dist/analytics/index.d.ts +8 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +7 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/middleware.d.ts +33 -0
- package/dist/analytics/middleware.d.ts.map +1 -0
- package/dist/analytics/middleware.js +99 -0
- package/dist/analytics/middleware.js.map +1 -0
- package/dist/analytics/transport.d.ts +11 -0
- package/dist/analytics/transport.d.ts.map +1 -0
- package/dist/analytics/transport.js +92 -0
- package/dist/analytics/transport.js.map +1 -0
- package/dist/analytics/types.d.ts +74 -0
- package/dist/analytics/types.d.ts.map +1 -0
- package/dist/analytics/types.js +6 -0
- package/dist/analytics/types.js.map +1 -0
- package/dist/config/api.d.ts +30 -0
- package/dist/config/api.d.ts.map +1 -0
- package/dist/config/api.js +32 -0
- package/dist/config/api.js.map +1 -0
- package/dist/config/cache.d.ts +31 -0
- package/dist/config/cache.d.ts.map +1 -0
- package/dist/config/cache.js +108 -0
- package/dist/config/cache.js.map +1 -0
- package/dist/config/displayThresholds.d.ts +83 -0
- package/dist/config/displayThresholds.d.ts.map +1 -0
- package/dist/config/displayThresholds.js +83 -0
- package/dist/config/displayThresholds.js.map +1 -0
- package/dist/config/tools.d.ts +44 -0
- package/dist/config/tools.d.ts.map +1 -0
- package/dist/config/tools.js +269 -0
- package/dist/config/tools.js.map +1 -0
- package/dist/errors/ApiError.d.ts +62 -0
- package/dist/errors/ApiError.d.ts.map +1 -0
- package/dist/errors/ApiError.js +171 -0
- package/dist/errors/ApiError.js.map +1 -0
- package/dist/handlers/airQualityHandler.d.ts +11 -0
- package/dist/handlers/airQualityHandler.d.ts.map +1 -0
- package/dist/handlers/airQualityHandler.js +154 -0
- package/dist/handlers/airQualityHandler.js.map +1 -0
- package/dist/handlers/alertsHandler.d.ts +11 -0
- package/dist/handlers/alertsHandler.d.ts.map +1 -0
- package/dist/handlers/alertsHandler.js +98 -0
- package/dist/handlers/alertsHandler.js.map +1 -0
- package/dist/handlers/currentConditionsHandler.d.ts +13 -0
- package/dist/handlers/currentConditionsHandler.d.ts.map +1 -0
- package/dist/handlers/currentConditionsHandler.js +296 -0
- package/dist/handlers/currentConditionsHandler.js.map +1 -0
- package/dist/handlers/forecastHandler.d.ts +16 -0
- package/dist/handlers/forecastHandler.d.ts.map +1 -0
- package/dist/handlers/forecastHandler.js +454 -0
- package/dist/handlers/forecastHandler.js.map +1 -0
- package/dist/handlers/historicalWeatherHandler.d.ts +12 -0
- package/dist/handlers/historicalWeatherHandler.d.ts.map +1 -0
- package/dist/handlers/historicalWeatherHandler.js +188 -0
- package/dist/handlers/historicalWeatherHandler.js.map +1 -0
- package/dist/handlers/lightningHandler.d.ts +14 -0
- package/dist/handlers/lightningHandler.d.ts.map +1 -0
- package/dist/handlers/lightningHandler.js +258 -0
- package/dist/handlers/lightningHandler.js.map +1 -0
- package/dist/handlers/locationHandler.d.ts +12 -0
- package/dist/handlers/locationHandler.d.ts.map +1 -0
- package/dist/handlers/locationHandler.js +149 -0
- package/dist/handlers/locationHandler.js.map +1 -0
- package/dist/handlers/marineConditionsHandler.d.ts +13 -0
- package/dist/handlers/marineConditionsHandler.d.ts.map +1 -0
- package/dist/handlers/marineConditionsHandler.js +270 -0
- package/dist/handlers/marineConditionsHandler.js.map +1 -0
- package/dist/handlers/riverConditionsHandler.d.ts +11 -0
- package/dist/handlers/riverConditionsHandler.d.ts.map +1 -0
- package/dist/handlers/riverConditionsHandler.js +176 -0
- package/dist/handlers/riverConditionsHandler.js.map +1 -0
- package/dist/handlers/savedLocationsHandler.d.ts +50 -0
- package/dist/handlers/savedLocationsHandler.d.ts.map +1 -0
- package/dist/handlers/savedLocationsHandler.js +397 -0
- package/dist/handlers/savedLocationsHandler.js.map +1 -0
- package/dist/handlers/statusHandler.d.ts +12 -0
- package/dist/handlers/statusHandler.d.ts.map +1 -0
- package/dist/handlers/statusHandler.js +115 -0
- package/dist/handlers/statusHandler.js.map +1 -0
- package/dist/handlers/weatherImageryHandler.d.ts +14 -0
- package/dist/handlers/weatherImageryHandler.d.ts.map +1 -0
- package/dist/handlers/weatherImageryHandler.js +143 -0
- package/dist/handlers/weatherImageryHandler.js.map +1 -0
- package/dist/handlers/wildfireHandler.d.ts +11 -0
- package/dist/handlers/wildfireHandler.d.ts.map +1 -0
- package/dist/handlers/wildfireHandler.js +186 -0
- package/dist/handlers/wildfireHandler.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +735 -0
- package/dist/index.js.map +1 -0
- package/dist/services/blitzortung.d.ts +67 -0
- package/dist/services/blitzortung.d.ts.map +1 -0
- package/dist/services/blitzortung.js +475 -0
- package/dist/services/blitzortung.js.map +1 -0
- package/dist/services/geocoding.d.ts +57 -0
- package/dist/services/geocoding.d.ts.map +1 -0
- package/dist/services/geocoding.js +393 -0
- package/dist/services/geocoding.js.map +1 -0
- package/dist/services/locationStore.d.ts +62 -0
- package/dist/services/locationStore.d.ts.map +1 -0
- package/dist/services/locationStore.js +201 -0
- package/dist/services/locationStore.js.map +1 -0
- package/dist/services/ncei.d.ts +61 -0
- package/dist/services/ncei.d.ts.map +1 -0
- package/dist/services/ncei.js +126 -0
- package/dist/services/ncei.js.map +1 -0
- package/dist/services/nifc.d.ts +44 -0
- package/dist/services/nifc.d.ts.map +1 -0
- package/dist/services/nifc.js +159 -0
- package/dist/services/nifc.js.map +1 -0
- package/dist/services/noaa.d.ts +161 -0
- package/dist/services/noaa.d.ts.map +1 -0
- package/dist/services/noaa.js +681 -0
- package/dist/services/noaa.js.map +1 -0
- package/dist/services/nominatim.d.ts +62 -0
- package/dist/services/nominatim.d.ts.map +1 -0
- package/dist/services/nominatim.js +254 -0
- package/dist/services/nominatim.js.map +1 -0
- package/dist/services/openmeteo.d.ts +189 -0
- package/dist/services/openmeteo.d.ts.map +1 -0
- package/dist/services/openmeteo.js +936 -0
- package/dist/services/openmeteo.js.map +1 -0
- package/dist/services/rainviewer.d.ts +37 -0
- package/dist/services/rainviewer.d.ts.map +1 -0
- package/dist/services/rainviewer.js +115 -0
- package/dist/services/rainviewer.js.map +1 -0
- package/dist/types/imagery.d.ts +82 -0
- package/dist/types/imagery.d.ts.map +1 -0
- package/dist/types/imagery.js +6 -0
- package/dist/types/imagery.js.map +1 -0
- package/dist/types/lightning.d.ts +89 -0
- package/dist/types/lightning.d.ts.map +1 -0
- package/dist/types/lightning.js +6 -0
- package/dist/types/lightning.js.map +1 -0
- package/dist/types/noaa.d.ts +535 -0
- package/dist/types/noaa.d.ts.map +1 -0
- package/dist/types/noaa.js +5 -0
- package/dist/types/noaa.js.map +1 -0
- package/dist/types/nominatim.d.ts +72 -0
- package/dist/types/nominatim.d.ts.map +1 -0
- package/dist/types/nominatim.js +6 -0
- package/dist/types/nominatim.js.map +1 -0
- package/dist/types/openmeteo.d.ts +583 -0
- package/dist/types/openmeteo.d.ts.map +1 -0
- package/dist/types/openmeteo.js +6 -0
- package/dist/types/openmeteo.js.map +1 -0
- package/dist/types/savedLocations.d.ts +58 -0
- package/dist/types/savedLocations.d.ts.map +1 -0
- package/dist/types/savedLocations.js +5 -0
- package/dist/types/savedLocations.js.map +1 -0
- package/dist/types/wildfire.d.ts +83 -0
- package/dist/types/wildfire.d.ts.map +1 -0
- package/dist/types/wildfire.js +5 -0
- package/dist/types/wildfire.js.map +1 -0
- package/dist/utils/airQuality.d.ts +54 -0
- package/dist/utils/airQuality.d.ts.map +1 -0
- package/dist/utils/airQuality.js +251 -0
- package/dist/utils/airQuality.js.map +1 -0
- package/dist/utils/cache.d.ts +69 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +164 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/distance.d.ts +25 -0
- package/dist/utils/distance.d.ts.map +1 -0
- package/dist/utils/distance.js +40 -0
- package/dist/utils/distance.js.map +1 -0
- package/dist/utils/fireWeather.d.ts +76 -0
- package/dist/utils/fireWeather.d.ts.map +1 -0
- package/dist/utils/fireWeather.js +243 -0
- package/dist/utils/fireWeather.js.map +1 -0
- package/dist/utils/geography.d.ts +79 -0
- package/dist/utils/geography.d.ts.map +1 -0
- package/dist/utils/geography.js +266 -0
- package/dist/utils/geography.js.map +1 -0
- package/dist/utils/geohash.d.ts +62 -0
- package/dist/utils/geohash.d.ts.map +1 -0
- package/dist/utils/geohash.js +146 -0
- package/dist/utils/geohash.js.map +1 -0
- package/dist/utils/locationResolver.d.ts +34 -0
- package/dist/utils/locationResolver.d.ts.map +1 -0
- package/dist/utils/locationResolver.js +120 -0
- package/dist/utils/locationResolver.js.map +1 -0
- package/dist/utils/logger.d.ts +75 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +153 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/marine.d.ts +59 -0
- package/dist/utils/marine.d.ts.map +1 -0
- package/dist/utils/marine.js +215 -0
- package/dist/utils/marine.js.map +1 -0
- package/dist/utils/normals.d.ts +86 -0
- package/dist/utils/normals.d.ts.map +1 -0
- package/dist/utils/normals.js +223 -0
- package/dist/utils/normals.js.map +1 -0
- package/dist/utils/snow.d.ts +45 -0
- package/dist/utils/snow.d.ts.map +1 -0
- package/dist/utils/snow.js +144 -0
- package/dist/utils/snow.js.map +1 -0
- package/dist/utils/temperatureConversion.d.ts +12 -0
- package/dist/utils/temperatureConversion.d.ts.map +1 -0
- package/dist/utils/temperatureConversion.js +17 -0
- package/dist/utils/temperatureConversion.js.map +1 -0
- package/dist/utils/timezone.d.ts +56 -0
- package/dist/utils/timezone.d.ts.map +1 -0
- package/dist/utils/timezone.js +167 -0
- package/dist/utils/timezone.js.map +1 -0
- package/dist/utils/units.d.ts +69 -0
- package/dist/utils/units.d.ts.map +1 -0
- package/dist/utils/units.js +158 -0
- package/dist/utils/units.js.map +1 -0
- package/dist/utils/validation.d.ts +89 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +177 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/version.d.ts +15 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +24 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for timezone-aware time formatting
|
|
3
|
+
* Uses Luxon for timezone support with native Intl API
|
|
4
|
+
*/
|
|
5
|
+
import { DateTime } from 'luxon';
|
|
6
|
+
/**
|
|
7
|
+
* Format an ISO 8601 datetime string in the specified timezone
|
|
8
|
+
* @param isoString - ISO 8601 datetime string (e.g., "2025-11-07T14:30:00+00:00")
|
|
9
|
+
* @param timezone - IANA timezone identifier (e.g., "America/New_York", "Asia/Tokyo")
|
|
10
|
+
* @param format - Optional format style ('full', 'long', 'medium', 'short')
|
|
11
|
+
* @returns Formatted datetime string in local timezone
|
|
12
|
+
*/
|
|
13
|
+
export function formatInTimezone(isoString, timezone, format = 'medium') {
|
|
14
|
+
try {
|
|
15
|
+
const dt = DateTime.fromISO(isoString, { setZone: false });
|
|
16
|
+
if (!dt.isValid) {
|
|
17
|
+
// Fallback to JavaScript Date if Luxon can't parse
|
|
18
|
+
return new Date(isoString).toLocaleString('en-US', { timeZone: timezone });
|
|
19
|
+
}
|
|
20
|
+
const zonedDt = dt.setZone(timezone);
|
|
21
|
+
// Format based on requested style
|
|
22
|
+
switch (format) {
|
|
23
|
+
case 'full':
|
|
24
|
+
return zonedDt.toLocaleString(DateTime.DATETIME_FULL);
|
|
25
|
+
case 'long':
|
|
26
|
+
return zonedDt.toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS);
|
|
27
|
+
case 'short':
|
|
28
|
+
return zonedDt.toLocaleString(DateTime.DATETIME_SHORT);
|
|
29
|
+
case 'medium':
|
|
30
|
+
default:
|
|
31
|
+
return zonedDt.toLocaleString(DateTime.DATETIME_MED);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// Fallback to standard Date formatting if anything goes wrong
|
|
36
|
+
return new Date(isoString).toLocaleString('en-US', { timeZone: timezone });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format a date-only ISO string in the specified timezone
|
|
41
|
+
* @param isoString - ISO 8601 datetime string
|
|
42
|
+
* @param timezone - IANA timezone identifier
|
|
43
|
+
* @returns Formatted date string (e.g., "Nov 7, 2025")
|
|
44
|
+
*/
|
|
45
|
+
export function formatDateInTimezone(isoString, timezone) {
|
|
46
|
+
try {
|
|
47
|
+
const dt = DateTime.fromISO(isoString, { setZone: false });
|
|
48
|
+
if (!dt.isValid) {
|
|
49
|
+
return new Date(isoString).toLocaleDateString('en-US', { timeZone: timezone });
|
|
50
|
+
}
|
|
51
|
+
const zonedDt = dt.setZone(timezone);
|
|
52
|
+
return zonedDt.toLocaleString(DateTime.DATE_MED);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
return new Date(isoString).toLocaleDateString('en-US', { timeZone: timezone });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Format a time-only ISO string in the specified timezone
|
|
60
|
+
* @param isoString - ISO 8601 datetime string
|
|
61
|
+
* @param timezone - IANA timezone identifier
|
|
62
|
+
* @returns Formatted time string (e.g., "2:30 PM EST")
|
|
63
|
+
*/
|
|
64
|
+
export function formatTimeInTimezone(isoString, timezone) {
|
|
65
|
+
try {
|
|
66
|
+
const dt = DateTime.fromISO(isoString, { setZone: false });
|
|
67
|
+
if (!dt.isValid) {
|
|
68
|
+
return new Date(isoString).toLocaleTimeString('en-US', {
|
|
69
|
+
timeZone: timezone,
|
|
70
|
+
timeZoneName: 'short'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const zonedDt = dt.setZone(timezone);
|
|
74
|
+
return zonedDt.toLocaleString(DateTime.TIME_WITH_SHORT_OFFSET);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return new Date(isoString).toLocaleTimeString('en-US', {
|
|
78
|
+
timeZone: timezone,
|
|
79
|
+
timeZoneName: 'short'
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get timezone abbreviation from IANA timezone identifier
|
|
85
|
+
* @param timezone - IANA timezone identifier (e.g., "America/New_York")
|
|
86
|
+
* @param datetime - Optional datetime to determine DST status
|
|
87
|
+
* @returns Timezone abbreviation (e.g., "EST" or "EDT")
|
|
88
|
+
*/
|
|
89
|
+
export function getTimezoneAbbreviation(timezone, datetime) {
|
|
90
|
+
try {
|
|
91
|
+
const dt = datetime
|
|
92
|
+
? DateTime.fromJSDate(datetime).setZone(timezone)
|
|
93
|
+
: DateTime.now().setZone(timezone);
|
|
94
|
+
return dt.offsetNameShort || dt.toFormat('ZZZZ');
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return timezone;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Detect timezone from coordinates using a simple heuristic
|
|
102
|
+
* This is a fallback when timezone is not provided by APIs
|
|
103
|
+
* @param latitude - Latitude
|
|
104
|
+
* @param longitude - Longitude
|
|
105
|
+
* @returns Best-guess IANA timezone identifier
|
|
106
|
+
*/
|
|
107
|
+
export function guessTimezoneFromCoords(latitude, longitude) {
|
|
108
|
+
// This is a simplified heuristic - in practice, APIs usually provide timezone
|
|
109
|
+
// For production use, consider integrating a proper coordinate-to-timezone library
|
|
110
|
+
// like tz-lookup or @photostructure/tz-lookup for accurate global coverage
|
|
111
|
+
// Map to common US timezones for North America based on longitude
|
|
112
|
+
if (latitude >= 24 && latitude <= 50 && longitude >= -125 && longitude <= -66) {
|
|
113
|
+
if (longitude >= -75)
|
|
114
|
+
return 'America/New_York';
|
|
115
|
+
if (longitude >= -87)
|
|
116
|
+
return 'America/Chicago';
|
|
117
|
+
if (longitude >= -104)
|
|
118
|
+
return 'America/Denver';
|
|
119
|
+
if (longitude >= -125)
|
|
120
|
+
return 'America/Los_Angeles';
|
|
121
|
+
}
|
|
122
|
+
// For international locations, default to UTC instead of server timezone
|
|
123
|
+
// This provides predictable, unambiguous timestamps for all users
|
|
124
|
+
// Note: The previous fallback to Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
125
|
+
// would return the server's local timezone, which is misleading for international queries
|
|
126
|
+
return 'UTC';
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Format a time range with timezone context
|
|
130
|
+
* @param startTime - Start time ISO string
|
|
131
|
+
* @param endTime - End time ISO string
|
|
132
|
+
* @param timezone - IANA timezone identifier
|
|
133
|
+
* @returns Formatted range (e.g., "Nov 7, 2:00 PM - 5:00 PM EST")
|
|
134
|
+
*/
|
|
135
|
+
export function formatTimeRangeInTimezone(startTime, endTime, timezone) {
|
|
136
|
+
try {
|
|
137
|
+
const start = DateTime.fromISO(startTime, { setZone: false }).setZone(timezone);
|
|
138
|
+
const end = DateTime.fromISO(endTime, { setZone: false }).setZone(timezone);
|
|
139
|
+
if (!start.isValid || !end.isValid) {
|
|
140
|
+
return `${formatInTimezone(startTime, timezone, 'short')} - ${formatInTimezone(endTime, timezone, 'short')}`;
|
|
141
|
+
}
|
|
142
|
+
// If same day, show: "Nov 7, 2:00 PM - 5:00 PM EST"
|
|
143
|
+
if (start.hasSame(end, 'day')) {
|
|
144
|
+
return `${start.toLocaleString(DateTime.DATE_MED)}, ${start.toLocaleString(DateTime.TIME_SIMPLE)} - ${end.toLocaleString(DateTime.TIME_SIMPLE)} ${start.offsetNameShort}`;
|
|
145
|
+
}
|
|
146
|
+
// Different days: "Nov 7, 2:00 PM - Nov 8, 5:00 PM EST"
|
|
147
|
+
return `${start.toLocaleString(DateTime.DATETIME_MED)} - ${end.toLocaleString(DateTime.DATETIME_MED)}`;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
return `${formatInTimezone(startTime, timezone, 'short')} - ${formatInTimezone(endTime, timezone, 'short')}`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check if a timezone is valid IANA timezone identifier
|
|
155
|
+
* @param timezone - Timezone string to validate
|
|
156
|
+
* @returns true if valid, false otherwise
|
|
157
|
+
*/
|
|
158
|
+
export function isValidTimezone(timezone) {
|
|
159
|
+
try {
|
|
160
|
+
DateTime.now().setZone(timezone);
|
|
161
|
+
return DateTime.now().setZone(timezone).isValid;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=timezone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timezone.js","sourceRoot":"","sources":["../../src/utils/timezone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for unit conversion and formatting
|
|
3
|
+
*/
|
|
4
|
+
import { QuantitativeValue } from '../types/noaa.js';
|
|
5
|
+
/**
|
|
6
|
+
* Extract numeric value from QuantitativeValue, handling null values
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractValue(qv: QuantitativeValue | undefined): number | null;
|
|
9
|
+
/**
|
|
10
|
+
* Convert Celsius to Fahrenheit
|
|
11
|
+
*/
|
|
12
|
+
export declare function celsiusToFahrenheit(celsius: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Convert meters per second to miles per hour
|
|
15
|
+
*/
|
|
16
|
+
export declare function mpsToMph(mps: number): number;
|
|
17
|
+
/**
|
|
18
|
+
* Convert kilometers per hour to miles per hour
|
|
19
|
+
*/
|
|
20
|
+
export declare function kphToMph(kph: number): number;
|
|
21
|
+
/**
|
|
22
|
+
* Convert meters to miles
|
|
23
|
+
*/
|
|
24
|
+
export declare function metersToMiles(meters: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Convert meters to feet
|
|
27
|
+
*/
|
|
28
|
+
export declare function metersToFeet(meters: number): number;
|
|
29
|
+
/**
|
|
30
|
+
* Convert Pascals to inches of mercury
|
|
31
|
+
*/
|
|
32
|
+
export declare function pascalsToInHg(pa: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Convert Pascals to millibars/hectopascals
|
|
35
|
+
*/
|
|
36
|
+
export declare function pascalsToMb(pa: number): number;
|
|
37
|
+
/**
|
|
38
|
+
* Format temperature with unit
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatTemperature(qv: QuantitativeValue | undefined, preferFahrenheit?: boolean): string;
|
|
41
|
+
/**
|
|
42
|
+
* Format wind speed with unit
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatWindSpeed(qv: QuantitativeValue | undefined): string;
|
|
45
|
+
/**
|
|
46
|
+
* Format visibility with unit
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatVisibility(qv: QuantitativeValue | undefined): string;
|
|
49
|
+
/**
|
|
50
|
+
* Format pressure with unit
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatPressure(qv: QuantitativeValue | undefined): string;
|
|
53
|
+
/**
|
|
54
|
+
* Format a percentage value
|
|
55
|
+
*/
|
|
56
|
+
export declare function formatPercentage(qv: QuantitativeValue | undefined): string;
|
|
57
|
+
/**
|
|
58
|
+
* Format wind direction from degrees to cardinal direction
|
|
59
|
+
*/
|
|
60
|
+
export declare function formatWindDirection(qv: QuantitativeValue | undefined): string;
|
|
61
|
+
/**
|
|
62
|
+
* Format date/time in readable format
|
|
63
|
+
*/
|
|
64
|
+
export declare function formatDateTime(isoString: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Format date only
|
|
67
|
+
*/
|
|
68
|
+
export declare function formatDate(isoString: string): string;
|
|
69
|
+
//# sourceMappingURL=units.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../src/utils/units.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAK7E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,EAAE,gBAAgB,UAAO,GAAG,MAAM,CAcpG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAazE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAO1E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAOxE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAK1E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAQ7E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUxD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQpD"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for unit conversion and formatting
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract numeric value from QuantitativeValue, handling null values
|
|
6
|
+
*/
|
|
7
|
+
export function extractValue(qv) {
|
|
8
|
+
if (!qv || qv.value === null || qv.value === undefined) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return qv.value;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Convert Celsius to Fahrenheit
|
|
15
|
+
*/
|
|
16
|
+
export function celsiusToFahrenheit(celsius) {
|
|
17
|
+
return (celsius * 9 / 5) + 32;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convert meters per second to miles per hour
|
|
21
|
+
*/
|
|
22
|
+
export function mpsToMph(mps) {
|
|
23
|
+
return mps * 2.23694;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Convert kilometers per hour to miles per hour
|
|
27
|
+
*/
|
|
28
|
+
export function kphToMph(kph) {
|
|
29
|
+
return kph * 0.621371;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert meters to miles
|
|
33
|
+
*/
|
|
34
|
+
export function metersToMiles(meters) {
|
|
35
|
+
return meters * 0.000621371;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Convert meters to feet
|
|
39
|
+
*/
|
|
40
|
+
export function metersToFeet(meters) {
|
|
41
|
+
return meters * 3.28084;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert Pascals to inches of mercury
|
|
45
|
+
*/
|
|
46
|
+
export function pascalsToInHg(pa) {
|
|
47
|
+
return pa * 0.0002953;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Convert Pascals to millibars/hectopascals
|
|
51
|
+
*/
|
|
52
|
+
export function pascalsToMb(pa) {
|
|
53
|
+
return pa / 100;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Format temperature with unit
|
|
57
|
+
*/
|
|
58
|
+
export function formatTemperature(qv, preferFahrenheit = true) {
|
|
59
|
+
const value = extractValue(qv);
|
|
60
|
+
if (value === null)
|
|
61
|
+
return 'N/A';
|
|
62
|
+
// NOAA returns temperature in Celsius in unitCode format "wmoUnit:degC"
|
|
63
|
+
if (qv?.unitCode?.includes('degC')) {
|
|
64
|
+
if (preferFahrenheit) {
|
|
65
|
+
return `${Math.round(celsiusToFahrenheit(value))}°F`;
|
|
66
|
+
}
|
|
67
|
+
return `${Math.round(value)}°C`;
|
|
68
|
+
}
|
|
69
|
+
// If already in Fahrenheit
|
|
70
|
+
return `${Math.round(value)}°F`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format wind speed with unit
|
|
74
|
+
*/
|
|
75
|
+
export function formatWindSpeed(qv) {
|
|
76
|
+
const value = extractValue(qv);
|
|
77
|
+
if (value === null)
|
|
78
|
+
return 'Calm';
|
|
79
|
+
// Convert to mph if needed
|
|
80
|
+
let mph = value;
|
|
81
|
+
if (qv?.unitCode?.includes('km_h')) {
|
|
82
|
+
mph = kphToMph(value);
|
|
83
|
+
}
|
|
84
|
+
else if (qv?.unitCode?.includes('m_s')) {
|
|
85
|
+
mph = mpsToMph(value);
|
|
86
|
+
}
|
|
87
|
+
return `${Math.round(mph)} mph`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format visibility with unit
|
|
91
|
+
*/
|
|
92
|
+
export function formatVisibility(qv) {
|
|
93
|
+
const value = extractValue(qv);
|
|
94
|
+
if (value === null)
|
|
95
|
+
return 'N/A';
|
|
96
|
+
// Convert meters to miles
|
|
97
|
+
const miles = metersToMiles(value);
|
|
98
|
+
return `${miles.toFixed(1)} miles`;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Format pressure with unit
|
|
102
|
+
*/
|
|
103
|
+
export function formatPressure(qv) {
|
|
104
|
+
const value = extractValue(qv);
|
|
105
|
+
if (value === null)
|
|
106
|
+
return 'N/A';
|
|
107
|
+
// Convert Pascals to inHg
|
|
108
|
+
const inHg = pascalsToInHg(value);
|
|
109
|
+
return `${inHg.toFixed(2)} inHg`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Format a percentage value
|
|
113
|
+
*/
|
|
114
|
+
export function formatPercentage(qv) {
|
|
115
|
+
const value = extractValue(qv);
|
|
116
|
+
if (value === null)
|
|
117
|
+
return 'N/A';
|
|
118
|
+
return `${Math.round(value)}%`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Format wind direction from degrees to cardinal direction
|
|
122
|
+
*/
|
|
123
|
+
export function formatWindDirection(qv) {
|
|
124
|
+
const degrees = extractValue(qv);
|
|
125
|
+
if (degrees === null)
|
|
126
|
+
return 'Variable';
|
|
127
|
+
const directions = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
|
128
|
+
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'];
|
|
129
|
+
const index = Math.round(degrees / 22.5) % 16;
|
|
130
|
+
return directions[index];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Format date/time in readable format
|
|
134
|
+
*/
|
|
135
|
+
export function formatDateTime(isoString) {
|
|
136
|
+
const date = new Date(isoString);
|
|
137
|
+
return date.toLocaleString('en-US', {
|
|
138
|
+
weekday: 'short',
|
|
139
|
+
month: 'short',
|
|
140
|
+
day: 'numeric',
|
|
141
|
+
hour: 'numeric',
|
|
142
|
+
minute: '2-digit',
|
|
143
|
+
timeZoneName: 'short'
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Format date only
|
|
148
|
+
*/
|
|
149
|
+
export function formatDate(isoString) {
|
|
150
|
+
const date = new Date(isoString);
|
|
151
|
+
return date.toLocaleDateString('en-US', {
|
|
152
|
+
weekday: 'long',
|
|
153
|
+
month: 'long',
|
|
154
|
+
day: 'numeric',
|
|
155
|
+
year: 'numeric'
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=units.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/utils/units.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation utilities for API parameters
|
|
3
|
+
* Provides runtime type checking and sanitization
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Validate that latitude is a valid number within range
|
|
7
|
+
* @param lat - Latitude value to validate
|
|
8
|
+
* @throws {Error} If latitude is invalid
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateLatitude(lat: unknown): asserts lat is number;
|
|
11
|
+
/**
|
|
12
|
+
* Validate that longitude is a valid number within range
|
|
13
|
+
* @param lon - Longitude value to validate
|
|
14
|
+
* @throws {Error} If longitude is invalid
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateLongitude(lon: unknown): asserts lon is number;
|
|
17
|
+
/**
|
|
18
|
+
* Validate coordinate pair
|
|
19
|
+
* @param args - Arguments object potentially containing coordinates
|
|
20
|
+
* @returns Validated coordinates
|
|
21
|
+
* @throws {Error} If coordinates are invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateCoordinates(args: unknown): {
|
|
24
|
+
latitude: number;
|
|
25
|
+
longitude: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validate a positive integer within optional range
|
|
29
|
+
* @param value - Value to validate
|
|
30
|
+
* @param name - Parameter name for error messages
|
|
31
|
+
* @param min - Minimum allowed value (inclusive)
|
|
32
|
+
* @param max - Maximum allowed value (inclusive)
|
|
33
|
+
* @returns Validated number
|
|
34
|
+
* @throws {Error} If value is invalid
|
|
35
|
+
*/
|
|
36
|
+
export declare function validatePositiveInteger(value: unknown, name: string, min?: number, max?: number): number;
|
|
37
|
+
/**
|
|
38
|
+
* Validate a boolean value
|
|
39
|
+
* @param value - Value to validate
|
|
40
|
+
* @param name - Parameter name for error messages
|
|
41
|
+
* @returns Validated boolean
|
|
42
|
+
* @throws {Error} If value is invalid
|
|
43
|
+
*/
|
|
44
|
+
export declare function validateBoolean(value: unknown, name: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Validate a date string in ISO format
|
|
47
|
+
* @param value - Value to validate
|
|
48
|
+
* @param name - Parameter name for error messages
|
|
49
|
+
* @returns Validated date string
|
|
50
|
+
* @throws {Error} If value is invalid
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateDateString(value: unknown, name: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Validate forecast days parameter
|
|
55
|
+
* @param args - Arguments object potentially containing days parameter
|
|
56
|
+
* @returns Validated days value (defaults to 7 if not provided)
|
|
57
|
+
* @throws {Error} If days parameter is invalid
|
|
58
|
+
*/
|
|
59
|
+
export declare function validateForecastDays(args: unknown): number;
|
|
60
|
+
/**
|
|
61
|
+
* Validate granularity parameter
|
|
62
|
+
* @param value - Value to validate
|
|
63
|
+
* @returns Validated granularity ('daily' or 'hourly')
|
|
64
|
+
* @throws {Error} If value is invalid
|
|
65
|
+
*/
|
|
66
|
+
export declare function validateGranularity(value: unknown): 'daily' | 'hourly';
|
|
67
|
+
/**
|
|
68
|
+
* Validate optional boolean with default
|
|
69
|
+
* @param value - Value to validate
|
|
70
|
+
* @param name - Parameter name for error messages
|
|
71
|
+
* @param defaultValue - Default value if undefined
|
|
72
|
+
* @returns Validated boolean
|
|
73
|
+
* @throws {Error} If value is invalid
|
|
74
|
+
*/
|
|
75
|
+
export declare function validateOptionalBoolean(value: unknown, name: string, defaultValue: boolean): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Validate historical weather parameters
|
|
78
|
+
* @param args - Arguments object
|
|
79
|
+
* @returns Validated parameters
|
|
80
|
+
* @throws {Error} If parameters are invalid
|
|
81
|
+
*/
|
|
82
|
+
export declare function validateHistoricalWeatherParams(args: unknown): {
|
|
83
|
+
latitude: number;
|
|
84
|
+
longitude: number;
|
|
85
|
+
start_date: string;
|
|
86
|
+
end_date: string;
|
|
87
|
+
limit?: number;
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,CAOpE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,CAOrE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAW1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAU,EACf,GAAG,GAAE,MAAgC,GACpC,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAY1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CActE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,OAAO,GACpB,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,OAAO,GAAG;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAoCA"}
|