@ryancardin/noaa-tides-currents-mcp-server 1.0.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.
Files changed (91) hide show
  1. package/.claude/settings.local.json +29 -0
  2. package/CLAUDE.md +71 -0
  3. package/Dockerfile +14 -0
  4. package/LICENSE +21 -0
  5. package/README.md +234 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +9 -0
  8. package/dist/interfaces/config.d.ts +6 -0
  9. package/dist/interfaces/config.js +1 -0
  10. package/dist/interfaces/moon.d.ts +65 -0
  11. package/dist/interfaces/moon.js +35 -0
  12. package/dist/interfaces/noaa.d.ts +334 -0
  13. package/dist/interfaces/noaa.js +98 -0
  14. package/dist/interfaces/parameters.d.ts +18 -0
  15. package/dist/interfaces/parameters.js +5 -0
  16. package/dist/interfaces/sun.d.ts +103 -0
  17. package/dist/interfaces/sun.js +45 -0
  18. package/dist/mcp-server.d.ts +12 -0
  19. package/dist/mcp-server.js +103 -0
  20. package/dist/moon-phase-service.d.ts +122 -0
  21. package/dist/moon-phase-service.js +187 -0
  22. package/dist/noaa-service.d.ts +60 -0
  23. package/dist/noaa-service.js +159 -0
  24. package/dist/schemas/common.d.ts +14 -0
  25. package/dist/schemas/common.js +18 -0
  26. package/dist/schemas/dpapi.d.ts +198 -0
  27. package/dist/schemas/dpapi.js +89 -0
  28. package/dist/server/config.d.ts +9 -0
  29. package/dist/server/config.js +40 -0
  30. package/dist/server/mcp-server.d.ts +12 -0
  31. package/dist/server/mcp-server.js +103 -0
  32. package/dist/services/dpapi-service.d.ts +72 -0
  33. package/dist/services/dpapi-service.js +164 -0
  34. package/dist/services/moon-phase-service.d.ts +34 -0
  35. package/dist/services/moon-phase-service.js +147 -0
  36. package/dist/services/noaa-parameters-service.d.ts +76 -0
  37. package/dist/services/noaa-parameters-service.js +128 -0
  38. package/dist/services/noaa-service.d.ts +52 -0
  39. package/dist/services/noaa-service.js +151 -0
  40. package/dist/services/sun-service.d.ts +60 -0
  41. package/dist/services/sun-service.js +234 -0
  42. package/dist/sun-service.d.ts +184 -0
  43. package/dist/sun-service.js +218 -0
  44. package/dist/tools/derived-product-tools.d.ts +6 -0
  45. package/dist/tools/derived-product-tools.js +168 -0
  46. package/dist/tools/index.d.ts +16 -0
  47. package/dist/tools/index.js +36 -0
  48. package/dist/tools/moon-tools.d.ts +6 -0
  49. package/dist/tools/moon-tools.js +69 -0
  50. package/dist/tools/parameter-tools.d.ts +6 -0
  51. package/dist/tools/parameter-tools.js +77 -0
  52. package/dist/tools/station-tools.d.ts +6 -0
  53. package/dist/tools/station-tools.js +51 -0
  54. package/dist/tools/sun-tools.d.ts +6 -0
  55. package/dist/tools/sun-tools.js +109 -0
  56. package/dist/tools/water-tools.d.ts +6 -0
  57. package/dist/tools/water-tools.js +150 -0
  58. package/dist/types/moon.d.ts +26 -0
  59. package/dist/types/moon.js +14 -0
  60. package/dist/types/sun.d.ts +49 -0
  61. package/dist/types/sun.js +19 -0
  62. package/dist/types.d.ts +337 -0
  63. package/dist/types.js +98 -0
  64. package/package.json +56 -0
  65. package/smithery.yaml +16 -0
  66. package/src/index.ts +13 -0
  67. package/src/interfaces/moon.ts +44 -0
  68. package/src/interfaces/noaa.ts +130 -0
  69. package/src/interfaces/parameters.ts +20 -0
  70. package/src/interfaces/sun.ts +57 -0
  71. package/src/schemas/common.ts +23 -0
  72. package/src/schemas/dpapi.ts +99 -0
  73. package/src/server/config.ts +43 -0
  74. package/src/server/mcp-server.ts +135 -0
  75. package/src/services/dpapi-service.ts +187 -0
  76. package/src/services/moon-phase-service.ts +167 -0
  77. package/src/services/noaa-parameters-service.ts +139 -0
  78. package/src/services/noaa-service.ts +171 -0
  79. package/src/services/sun-service.ts +275 -0
  80. package/src/tools/derived-product-tools.ts +180 -0
  81. package/src/tools/index.ts +40 -0
  82. package/src/tools/moon-tools.ts +79 -0
  83. package/src/tools/parameter-tools.ts +82 -0
  84. package/src/tools/station-tools.ts +57 -0
  85. package/src/tools/sun-tools.ts +120 -0
  86. package/src/tools/water-tools.ts +166 -0
  87. package/src/types/moon.ts +27 -0
  88. package/src/types/sun.ts +51 -0
  89. package/src/types/suncalc.d.ts +110 -0
  90. package/test-dpapi.js +0 -0
  91. package/tsconfig.json +15 -0
@@ -0,0 +1,151 @@
1
+ import axios from 'axios';
2
+ // Base URLs for the different NOAA APIs
3
+ const DATA_API_BASE_URL = 'https://api.tidesandcurrents.noaa.gov/api/prod/datagetter';
4
+ const METADATA_API_BASE_URL = 'https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi';
5
+ /**
6
+ * Service for interacting with NOAA Tides and Currents APIs
7
+ */
8
+ export class NoaaService {
9
+ /**
10
+ * Build parameters for the API request
11
+ * @param params Parameters for the request
12
+ * @returns URL-encoded parameters string
13
+ */
14
+ buildParams(params) {
15
+ // Remove undefined and null values
16
+ const filteredParams = Object.entries(params)
17
+ .filter(([_, value]) => value !== undefined && value !== null)
18
+ .reduce((acc, [key, value]) => {
19
+ acc[key] = value;
20
+ return acc;
21
+ }, {});
22
+ // Convert to URL parameters
23
+ return new URLSearchParams(filteredParams).toString();
24
+ }
25
+ /**
26
+ * Make a request to the Data API
27
+ * @param params Parameters for the request
28
+ * @returns Response data
29
+ */
30
+ async fetchDataApi(params) {
31
+ try {
32
+ const queryParams = this.buildParams(params);
33
+ const url = `${DATA_API_BASE_URL}?${queryParams}`;
34
+ const response = await axios.get(url);
35
+ return response.data;
36
+ }
37
+ catch (error) {
38
+ if (axios.isAxiosError(error) && error.response) {
39
+ throw new Error(`NOAA API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
40
+ }
41
+ throw error;
42
+ }
43
+ }
44
+ /**
45
+ * Make a request to the Metadata API
46
+ * @param endpoint Endpoint path
47
+ * @param params Parameters for the request
48
+ * @returns Response data
49
+ */
50
+ async fetchMetadataApi(endpoint, params = {}) {
51
+ try {
52
+ const queryParams = this.buildParams(params);
53
+ const url = `${METADATA_API_BASE_URL}${endpoint}${queryParams ? '?' + queryParams : ''}`;
54
+ const response = await axios.get(url);
55
+ return response.data;
56
+ }
57
+ catch (error) {
58
+ if (axios.isAxiosError(error) && error.response) {
59
+ throw new Error(`NOAA API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
60
+ }
61
+ throw error;
62
+ }
63
+ }
64
+ /**
65
+ * Get water level data
66
+ */
67
+ async getWaterLevels(params) {
68
+ return this.fetchDataApi({
69
+ ...params,
70
+ product: 'water_level'
71
+ });
72
+ }
73
+ /**
74
+ * Get tide predictions
75
+ */
76
+ async getTidePredictions(params) {
77
+ return this.fetchDataApi({
78
+ ...params,
79
+ product: 'predictions'
80
+ });
81
+ }
82
+ /**
83
+ * Get currents data
84
+ */
85
+ async getCurrents(params) {
86
+ return this.fetchDataApi({
87
+ ...params,
88
+ product: 'currents'
89
+ });
90
+ }
91
+ /**
92
+ * Get current predictions
93
+ */
94
+ async getCurrentPredictions(params) {
95
+ return this.fetchDataApi({
96
+ ...params,
97
+ product: 'currents_predictions'
98
+ });
99
+ }
100
+ /**
101
+ * Get meteorological data (air_temperature, wind, etc.)
102
+ */
103
+ async getMeteorologicalData(params) {
104
+ const { product, ...rest } = params;
105
+ return this.fetchDataApi({
106
+ ...rest,
107
+ product
108
+ });
109
+ }
110
+ /**
111
+ * Get list of stations
112
+ */
113
+ async getStations(params) {
114
+ const { type, name, lat_min, lat_max, lon_min, lon_max, state, limit, offset, sort_by, sort_order, ...rest } = params;
115
+ const endpoint = '/stations.' + (rest.format || 'json');
116
+ // Build query parameters with all the filters
117
+ const queryParams = { ...rest };
118
+ // Add filters only if they are defined
119
+ if (type)
120
+ queryParams.type = type;
121
+ if (name)
122
+ queryParams.name = name;
123
+ if (lat_min !== undefined)
124
+ queryParams.lat_min = lat_min;
125
+ if (lat_max !== undefined)
126
+ queryParams.lat_max = lat_max;
127
+ if (lon_min !== undefined)
128
+ queryParams.lon_min = lon_min;
129
+ if (lon_max !== undefined)
130
+ queryParams.lon_max = lon_max;
131
+ if (state)
132
+ queryParams.state = state;
133
+ if (limit !== undefined)
134
+ queryParams.limit = limit;
135
+ if (offset !== undefined)
136
+ queryParams.offset = offset;
137
+ if (sort_by)
138
+ queryParams.sort_by = sort_by;
139
+ if (sort_order)
140
+ queryParams.sort_order = sort_order;
141
+ return this.fetchMetadataApi(endpoint, queryParams);
142
+ }
143
+ /**
144
+ * Get station details
145
+ */
146
+ async getStationDetails(params) {
147
+ const { station, ...rest } = params;
148
+ const endpoint = `/stations/${station}/details.` + (rest.format || 'json');
149
+ return this.fetchMetadataApi(endpoint, rest);
150
+ }
151
+ }
@@ -0,0 +1,60 @@
1
+ import { SunTimesParams, SunTimesRangeParams, SunPositionParams, NextSunEventParams } from '../interfaces/sun.js';
2
+ import { SunTimesInfo, SunPositionInfo } from '../types/sun.js';
3
+ /**
4
+ * Service for sun calculations
5
+ */
6
+ export declare class SunService {
7
+ /**
8
+ * Get sun times for a specific date and location
9
+ * @param params Parameters for the request
10
+ * @returns Sun times information
11
+ */
12
+ getSunTimes(params: SunTimesParams): SunTimesInfo;
13
+ /**
14
+ * Get sun times for a date range
15
+ * @param params Parameters for the request
16
+ * @returns Array of sun times information
17
+ */
18
+ getSunTimesRange(params: SunTimesRangeParams): SunTimesInfo[];
19
+ /**
20
+ * Get sun position for a specific date, time, and location
21
+ * @param params Parameters for the request
22
+ * @returns Sun position information
23
+ */
24
+ getSunPosition(params: SunPositionParams): SunPositionInfo;
25
+ /**
26
+ * Get the next occurrence(s) of a specific sun event
27
+ * @param params Parameters for the request
28
+ * @returns Array of dates for the next occurrences of the specified event
29
+ */
30
+ getNextSunEvent(params: NextSunEventParams): {
31
+ date: string;
32
+ time: string;
33
+ event: string;
34
+ }[];
35
+ /**
36
+ * Calculate approximate equatorial coordinates (right ascension and declination)
37
+ * from horizontal coordinates (azimuth and altitude)
38
+ * Note: This is a simplified calculation and may not be precise
39
+ * @param date Date of observation
40
+ * @param azimuth Azimuth in radians
41
+ * @param altitude Altitude in radians
42
+ * @param latitude Observer's latitude
43
+ * @param longitude Observer's longitude
44
+ * @returns Approximate equatorial coordinates
45
+ */
46
+ private calculateEquatorialCoordinates;
47
+ /**
48
+ * Calculate approximate local sidereal time
49
+ * @param date Date of observation
50
+ * @param longitude Observer's longitude
51
+ * @returns Local sidereal time in radians
52
+ */
53
+ private calculateLocalSiderealTime;
54
+ /**
55
+ * Calculate Julian day from date
56
+ * @param date Date to convert
57
+ * @returns Julian day
58
+ */
59
+ private calculateJulianDay;
60
+ }
@@ -0,0 +1,234 @@
1
+ import SunCalc from 'suncalc';
2
+ /**
3
+ * Service for sun calculations
4
+ */
5
+ export class SunService {
6
+ /**
7
+ * Get sun times for a specific date and location
8
+ * @param params Parameters for the request
9
+ * @returns Sun times information
10
+ */
11
+ getSunTimes(params) {
12
+ const date = params.date ? new Date(params.date) : new Date();
13
+ const { latitude, longitude } = params;
14
+ // Get sun times data
15
+ const sunTimes = SunCalc.getTimes(date, latitude, longitude);
16
+ // Format times or return null if not available
17
+ const formatTime = (time) => {
18
+ if (!time || isNaN(time.getTime()))
19
+ return null;
20
+ if (params.timezone) {
21
+ try {
22
+ return time.toLocaleTimeString('en-US', { timeZone: params.timezone });
23
+ }
24
+ catch (error) {
25
+ // If timezone is invalid, fall back to ISO string
26
+ console.warn(`Invalid timezone: ${params.timezone}. Using UTC.`);
27
+ }
28
+ }
29
+ return time.toISOString();
30
+ };
31
+ // Calculate day length in minutes
32
+ const sunrise = sunTimes.sunrise;
33
+ const sunset = sunTimes.sunset;
34
+ let dayLength = 0;
35
+ if (sunrise && sunset && !isNaN(sunrise.getTime()) && !isNaN(sunset.getTime())) {
36
+ dayLength = (sunset.getTime() - sunrise.getTime()) / (60 * 1000);
37
+ }
38
+ return {
39
+ date: date.toISOString().split('T')[0],
40
+ sunrise: formatTime(sunTimes.sunrise),
41
+ sunset: formatTime(sunTimes.sunset),
42
+ solarNoon: formatTime(sunTimes.solarNoon),
43
+ dawn: formatTime(sunTimes.dawn),
44
+ dusk: formatTime(sunTimes.dusk),
45
+ nightStart: formatTime(sunTimes.night),
46
+ nightEnd: formatTime(sunTimes.nightEnd),
47
+ goldenHourStart: formatTime(sunTimes.goldenHour),
48
+ goldenHourEnd: formatTime(sunTimes.goldenHourEnd),
49
+ nauticalDawn: formatTime(sunTimes.nauticalDawn),
50
+ nauticalDusk: formatTime(sunTimes.nauticalDusk),
51
+ astronomicalDawn: formatTime(sunTimes.astronomicalDawn),
52
+ astronomicalDusk: formatTime(sunTimes.astronomicalDusk),
53
+ dayLength
54
+ };
55
+ }
56
+ /**
57
+ * Get sun times for a date range
58
+ * @param params Parameters for the request
59
+ * @returns Array of sun times information
60
+ */
61
+ getSunTimesRange(params) {
62
+ const startDate = new Date(params.start_date);
63
+ const endDate = new Date(params.end_date);
64
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
65
+ throw new Error('Invalid date format. Please use YYYY-MM-DD format.');
66
+ }
67
+ if (startDate > endDate) {
68
+ throw new Error('Start date must be before end date.');
69
+ }
70
+ const result = [];
71
+ const currentDate = new Date(startDate);
72
+ while (currentDate <= endDate) {
73
+ result.push(this.getSunTimes({
74
+ date: currentDate.toISOString().split('T')[0],
75
+ latitude: params.latitude,
76
+ longitude: params.longitude,
77
+ timezone: params.timezone
78
+ }));
79
+ // Move to next day
80
+ currentDate.setDate(currentDate.getDate() + 1);
81
+ }
82
+ return result;
83
+ }
84
+ /**
85
+ * Get sun position for a specific date, time, and location
86
+ * @param params Parameters for the request
87
+ * @returns Sun position information
88
+ */
89
+ getSunPosition(params) {
90
+ const date = params.date ? new Date(params.date) : new Date();
91
+ const time = params.time;
92
+ const { latitude, longitude } = params;
93
+ // Set the time if provided
94
+ if (time) {
95
+ const [hours, minutes, seconds] = time.split(':').map(Number);
96
+ if (!isNaN(hours) && !isNaN(minutes) && (!seconds || !isNaN(seconds))) {
97
+ date.setHours(hours, minutes, seconds || 0, 0);
98
+ }
99
+ else {
100
+ throw new Error('Invalid time format. Please use HH:MM:SS format.');
101
+ }
102
+ }
103
+ // Get sun position data
104
+ const position = SunCalc.getPosition(date, latitude, longitude);
105
+ // Calculate right ascension and declination (approximate values)
106
+ // Note: These are approximate calculations and may not be precise
107
+ const equatorialCoords = this.calculateEquatorialCoordinates(date, position.azimuth, position.altitude, latitude, longitude);
108
+ return {
109
+ date: date.toISOString().split('T')[0],
110
+ time: date.toISOString().split('T')[1].split('.')[0],
111
+ azimuth: position.azimuth * (180 / Math.PI),
112
+ altitude: position.altitude * (180 / Math.PI),
113
+ declination: equatorialCoords.declination,
114
+ rightAscension: equatorialCoords.rightAscension
115
+ };
116
+ }
117
+ /**
118
+ * Get the next occurrence(s) of a specific sun event
119
+ * @param params Parameters for the request
120
+ * @returns Array of dates for the next occurrences of the specified event
121
+ */
122
+ getNextSunEvent(params) {
123
+ const startDate = params.date ? new Date(params.date) : new Date();
124
+ const count = params.count !== undefined ? params.count : 1;
125
+ const { latitude, longitude } = params;
126
+ const timezone = params.timezone !== undefined ? params.timezone : 'UTC';
127
+ const results = [];
128
+ let currentDate = new Date(startDate);
129
+ // Find the next occurrences
130
+ while (results.length < count) {
131
+ const sunTimes = SunCalc.getTimes(currentDate, latitude, longitude);
132
+ const eventTime = sunTimes[params.event];
133
+ if (eventTime && !isNaN(eventTime.getTime()) && eventTime > startDate) {
134
+ let formattedTime;
135
+ try {
136
+ formattedTime = eventTime.toLocaleTimeString('en-US', { timeZone: timezone });
137
+ }
138
+ catch (error) {
139
+ // If timezone is invalid, fall back to ISO string
140
+ console.warn(`Invalid timezone: ${timezone}. Using UTC.`);
141
+ formattedTime = eventTime.toISOString().split('T')[1].split('.')[0];
142
+ }
143
+ results.push({
144
+ date: eventTime.toISOString().split('T')[0],
145
+ time: formattedTime,
146
+ event: params.event
147
+ });
148
+ // Move to next day to find the next occurrence
149
+ currentDate.setDate(currentDate.getDate() + 1);
150
+ }
151
+ else {
152
+ // Event not found for this day, try next day
153
+ currentDate.setDate(currentDate.getDate() + 1);
154
+ }
155
+ // Safety check to prevent infinite loops
156
+ if (results.length === 0 && currentDate.getTime() - startDate.getTime() > 366 * 24 * 60 * 60 * 1000) {
157
+ throw new Error('Could not find the specified sun event within a year.');
158
+ }
159
+ }
160
+ return results;
161
+ }
162
+ /**
163
+ * Calculate approximate equatorial coordinates (right ascension and declination)
164
+ * from horizontal coordinates (azimuth and altitude)
165
+ * Note: This is a simplified calculation and may not be precise
166
+ * @param date Date of observation
167
+ * @param azimuth Azimuth in radians
168
+ * @param altitude Altitude in radians
169
+ * @param latitude Observer's latitude
170
+ * @param longitude Observer's longitude
171
+ * @returns Approximate equatorial coordinates
172
+ */
173
+ calculateEquatorialCoordinates(date, azimuth, altitude, latitude, longitude) {
174
+ // Convert degrees to radians
175
+ const lat = latitude * (Math.PI / 180);
176
+ // Calculate hour angle and declination
177
+ const sinDec = Math.sin(altitude) * Math.sin(lat) + Math.cos(altitude) * Math.cos(lat) * Math.cos(azimuth);
178
+ const declination = Math.asin(sinDec) * (180 / Math.PI);
179
+ const cosH = (Math.sin(altitude) - Math.sin(lat) * sinDec) / (Math.cos(lat) * Math.cos(declination * (Math.PI / 180)));
180
+ const hourAngle = Math.acos(Math.max(-1, Math.min(1, cosH)));
181
+ // Adjust hour angle based on azimuth
182
+ const adjustedHourAngle = (azimuth > 0 && azimuth < Math.PI) ? (2 * Math.PI - hourAngle) : hourAngle;
183
+ // Calculate right ascension
184
+ const localSiderealTime = this.calculateLocalSiderealTime(date, longitude);
185
+ let rightAscension = (localSiderealTime - adjustedHourAngle) * (12 / Math.PI);
186
+ // Normalize right ascension to 0-24 hours
187
+ rightAscension = rightAscension % 24;
188
+ if (rightAscension < 0)
189
+ rightAscension += 24;
190
+ return { rightAscension, declination };
191
+ }
192
+ /**
193
+ * Calculate approximate local sidereal time
194
+ * @param date Date of observation
195
+ * @param longitude Observer's longitude
196
+ * @returns Local sidereal time in radians
197
+ */
198
+ calculateLocalSiderealTime(date, longitude) {
199
+ // Calculate days since J2000.0
200
+ const jd = this.calculateJulianDay(date);
201
+ const d = jd - 2451545.0;
202
+ // Calculate Greenwich Mean Sidereal Time
203
+ const gmst = (18.697374558 + 24.06570982441908 * d) % 24;
204
+ // Convert longitude to hours and calculate local sidereal time
205
+ const longitudeHours = longitude / 15;
206
+ let lst = gmst + longitudeHours;
207
+ // Normalize to 0-24 hours
208
+ lst = lst % 24;
209
+ if (lst < 0)
210
+ lst += 24;
211
+ // Convert to radians
212
+ return lst * (Math.PI / 12);
213
+ }
214
+ /**
215
+ * Calculate Julian day from date
216
+ * @param date Date to convert
217
+ * @returns Julian day
218
+ */
219
+ calculateJulianDay(date) {
220
+ const y = date.getFullYear();
221
+ const m = date.getMonth() + 1;
222
+ const d = date.getDate();
223
+ // Calculate Julian day
224
+ const jd = 367 * y - Math.floor(7 * (y + Math.floor((m + 9) / 12)) / 4) -
225
+ Math.floor(3 * (Math.floor((y + (m - 9) / 7) / 100) + 1) / 4) +
226
+ Math.floor(275 * m / 9) + d + 1721028.5;
227
+ // Add time of day
228
+ const hours = date.getUTCHours();
229
+ const minutes = date.getUTCMinutes();
230
+ const seconds = date.getUTCSeconds();
231
+ const milliseconds = date.getUTCMilliseconds();
232
+ return jd + (hours + minutes / 60 + seconds / 3600 + milliseconds / 3600000) / 24;
233
+ }
234
+ }
@@ -0,0 +1,184 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Sun event types
4
+ */
5
+ export declare enum SunEventType {
6
+ SUNRISE = "sunrise",
7
+ SUNSET = "sunset",
8
+ DAWN = "dawn",
9
+ DUSK = "dusk",
10
+ SOLAR_NOON = "solarNoon",
11
+ NIGHT_START = "night",
12
+ NIGHT_END = "nightEnd",
13
+ GOLDEN_HOUR_START = "goldenHourStart",
14
+ GOLDEN_HOUR_END = "goldenHourEnd",
15
+ NAUTICAL_DAWN = "nauticalDawn",
16
+ NAUTICAL_DUSK = "nauticalDusk",
17
+ ASTRONOMICAL_DAWN = "astronomicalDawn",
18
+ ASTRONOMICAL_DUSK = "astronomicalDusk"
19
+ }
20
+ /**
21
+ * Sun times information
22
+ */
23
+ export interface SunTimesInfo {
24
+ date: string;
25
+ sunrise: string | null;
26
+ sunset: string | null;
27
+ solarNoon: string | null;
28
+ dawn: string | null;
29
+ dusk: string | null;
30
+ nightStart: string | null;
31
+ nightEnd: string | null;
32
+ goldenHourStart: string | null;
33
+ goldenHourEnd: string | null;
34
+ nauticalDawn: string | null;
35
+ nauticalDusk: string | null;
36
+ astronomicalDawn: string | null;
37
+ astronomicalDusk: string | null;
38
+ dayLength: number;
39
+ }
40
+ /**
41
+ * Sun position information
42
+ */
43
+ export interface SunPositionInfo {
44
+ date: string;
45
+ time: string;
46
+ azimuth: number;
47
+ altitude: number;
48
+ declination: number;
49
+ rightAscension: number;
50
+ }
51
+ /**
52
+ * Parameters for getting sun times
53
+ */
54
+ export declare const SunTimesParamsSchema: z.ZodObject<{
55
+ date: z.ZodOptional<z.ZodString>;
56
+ latitude: z.ZodNumber;
57
+ longitude: z.ZodNumber;
58
+ format: z.ZodOptional<z.ZodEnum<["json", "text"]>>;
59
+ timezone: z.ZodOptional<z.ZodString>;
60
+ }, "strip", z.ZodTypeAny, {
61
+ latitude: number;
62
+ longitude: number;
63
+ date?: string | undefined;
64
+ format?: "text" | "json" | undefined;
65
+ timezone?: string | undefined;
66
+ }, {
67
+ latitude: number;
68
+ longitude: number;
69
+ date?: string | undefined;
70
+ format?: "text" | "json" | undefined;
71
+ timezone?: string | undefined;
72
+ }>;
73
+ export type SunTimesParams = z.infer<typeof SunTimesParamsSchema>;
74
+ /**
75
+ * Parameters for getting sun times for a date range
76
+ */
77
+ export declare const SunTimesRangeParamsSchema: z.ZodObject<{
78
+ start_date: z.ZodString;
79
+ end_date: z.ZodString;
80
+ latitude: z.ZodNumber;
81
+ longitude: z.ZodNumber;
82
+ format: z.ZodOptional<z.ZodEnum<["json", "text"]>>;
83
+ timezone: z.ZodOptional<z.ZodString>;
84
+ }, "strip", z.ZodTypeAny, {
85
+ latitude: number;
86
+ longitude: number;
87
+ start_date: string;
88
+ end_date: string;
89
+ format?: "text" | "json" | undefined;
90
+ timezone?: string | undefined;
91
+ }, {
92
+ latitude: number;
93
+ longitude: number;
94
+ start_date: string;
95
+ end_date: string;
96
+ format?: "text" | "json" | undefined;
97
+ timezone?: string | undefined;
98
+ }>;
99
+ export type SunTimesRangeParams = z.infer<typeof SunTimesRangeParamsSchema>;
100
+ /**
101
+ * Parameters for getting sun position
102
+ */
103
+ export declare const SunPositionParamsSchema: z.ZodObject<{
104
+ date: z.ZodOptional<z.ZodString>;
105
+ time: z.ZodOptional<z.ZodString>;
106
+ latitude: z.ZodNumber;
107
+ longitude: z.ZodNumber;
108
+ format: z.ZodOptional<z.ZodEnum<["json", "text"]>>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ latitude: number;
111
+ longitude: number;
112
+ time?: string | undefined;
113
+ date?: string | undefined;
114
+ format?: "text" | "json" | undefined;
115
+ }, {
116
+ latitude: number;
117
+ longitude: number;
118
+ time?: string | undefined;
119
+ date?: string | undefined;
120
+ format?: "text" | "json" | undefined;
121
+ }>;
122
+ export type SunPositionParams = z.infer<typeof SunPositionParamsSchema>;
123
+ /**
124
+ * Parameters for finding the next sun event
125
+ */
126
+ export declare const NextSunEventParamsSchema: z.ZodObject<{
127
+ event: z.ZodNativeEnum<typeof SunEventType>;
128
+ date: z.ZodOptional<z.ZodString>;
129
+ latitude: z.ZodNumber;
130
+ longitude: z.ZodNumber;
131
+ count: z.ZodOptional<z.ZodNumber>;
132
+ format: z.ZodOptional<z.ZodEnum<["json", "text"]>>;
133
+ timezone: z.ZodOptional<z.ZodString>;
134
+ }, "strip", z.ZodTypeAny, {
135
+ event: SunEventType;
136
+ latitude: number;
137
+ longitude: number;
138
+ date?: string | undefined;
139
+ format?: "text" | "json" | undefined;
140
+ count?: number | undefined;
141
+ timezone?: string | undefined;
142
+ }, {
143
+ event: SunEventType;
144
+ latitude: number;
145
+ longitude: number;
146
+ date?: string | undefined;
147
+ format?: "text" | "json" | undefined;
148
+ count?: number | undefined;
149
+ timezone?: string | undefined;
150
+ }>;
151
+ export type NextSunEventParams = z.infer<typeof NextSunEventParamsSchema>;
152
+ /**
153
+ * Service for sun calculations
154
+ */
155
+ export declare class SunService {
156
+ /**
157
+ * Get sun times for a specific date and location
158
+ * @param params Parameters for the request
159
+ * @returns Sun times information
160
+ */
161
+ getSunTimes(params: SunTimesParams): SunTimesInfo;
162
+ /**
163
+ * Get sun times for a date range
164
+ * @param params Parameters for the request
165
+ * @returns Array of sun times information
166
+ */
167
+ getSunTimesRange(params: SunTimesRangeParams): SunTimesInfo[];
168
+ /**
169
+ * Get sun position for a specific date, time, and location
170
+ * @param params Parameters for the request
171
+ * @returns Sun position information
172
+ */
173
+ getSunPosition(params: SunPositionParams): SunPositionInfo;
174
+ /**
175
+ * Get the next occurrence(s) of a specific sun event
176
+ * @param params Parameters for the request
177
+ * @returns Array of dates for the next occurrences of the specified event
178
+ */
179
+ getNextSunEvent(params: NextSunEventParams): {
180
+ date: string;
181
+ time: string;
182
+ event: string;
183
+ }[];
184
+ }