meteo-lt-sdk 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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -0
  3. package/dist/__tests__/test-utils.d.ts +240 -0
  4. package/dist/__tests__/test-utils.d.ts.map +1 -0
  5. package/dist/__tests__/test-utils.js +278 -0
  6. package/dist/__tests__/test-utils.js.map +1 -0
  7. package/dist/api/hydro-stations.d.ts +133 -0
  8. package/dist/api/hydro-stations.d.ts.map +1 -0
  9. package/dist/api/hydro-stations.js +148 -0
  10. package/dist/api/hydro-stations.js.map +1 -0
  11. package/dist/api/index.d.ts +8 -0
  12. package/dist/api/index.d.ts.map +1 -0
  13. package/dist/api/index.js +8 -0
  14. package/dist/api/index.js.map +1 -0
  15. package/dist/api/places.d.ts +78 -0
  16. package/dist/api/places.d.ts.map +1 -0
  17. package/dist/api/places.js +87 -0
  18. package/dist/api/places.js.map +1 -0
  19. package/dist/api/stations.d.ts +80 -0
  20. package/dist/api/stations.d.ts.map +1 -0
  21. package/dist/api/stations.js +89 -0
  22. package/dist/api/stations.js.map +1 -0
  23. package/dist/client/MeteoClient.d.ts +85 -0
  24. package/dist/client/MeteoClient.d.ts.map +1 -0
  25. package/dist/client/MeteoClient.js +92 -0
  26. package/dist/client/MeteoClient.js.map +1 -0
  27. package/dist/client/config.d.ts +57 -0
  28. package/dist/client/config.d.ts.map +1 -0
  29. package/dist/client/config.js +29 -0
  30. package/dist/client/config.js.map +1 -0
  31. package/dist/client/http.d.ts +36 -0
  32. package/dist/client/http.d.ts.map +1 -0
  33. package/dist/client/http.js +115 -0
  34. package/dist/client/http.js.map +1 -0
  35. package/dist/client/index.d.ts +8 -0
  36. package/dist/client/index.d.ts.map +1 -0
  37. package/dist/client/index.js +7 -0
  38. package/dist/client/index.js.map +1 -0
  39. package/dist/client/rate-limiter.d.ts +64 -0
  40. package/dist/client/rate-limiter.d.ts.map +1 -0
  41. package/dist/client/rate-limiter.js +150 -0
  42. package/dist/client/rate-limiter.js.map +1 -0
  43. package/dist/index.d.ts +36 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +43 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/schemas/coordinates.d.ts +26 -0
  48. package/dist/schemas/coordinates.d.ts.map +1 -0
  49. package/dist/schemas/coordinates.js +32 -0
  50. package/dist/schemas/coordinates.js.map +1 -0
  51. package/dist/schemas/forecasts.d.ts +93 -0
  52. package/dist/schemas/forecasts.d.ts.map +1 -0
  53. package/dist/schemas/forecasts.js +38 -0
  54. package/dist/schemas/forecasts.js.map +1 -0
  55. package/dist/schemas/hydro-stations.d.ts +172 -0
  56. package/dist/schemas/hydro-stations.d.ts.map +1 -0
  57. package/dist/schemas/hydro-stations.js +99 -0
  58. package/dist/schemas/hydro-stations.js.map +1 -0
  59. package/dist/schemas/index.d.ts +10 -0
  60. package/dist/schemas/index.d.ts.map +1 -0
  61. package/dist/schemas/index.js +15 -0
  62. package/dist/schemas/index.js.map +1 -0
  63. package/dist/schemas/places.d.ts +77 -0
  64. package/dist/schemas/places.d.ts.map +1 -0
  65. package/dist/schemas/places.js +45 -0
  66. package/dist/schemas/places.js.map +1 -0
  67. package/dist/schemas/stations.d.ts +167 -0
  68. package/dist/schemas/stations.d.ts.map +1 -0
  69. package/dist/schemas/stations.js +69 -0
  70. package/dist/schemas/stations.js.map +1 -0
  71. package/dist/types/conditions.d.ts +47 -0
  72. package/dist/types/conditions.d.ts.map +1 -0
  73. package/dist/types/conditions.js +132 -0
  74. package/dist/types/conditions.js.map +1 -0
  75. package/dist/types/coordinates.d.ts +63 -0
  76. package/dist/types/coordinates.d.ts.map +1 -0
  77. package/dist/types/coordinates.js +58 -0
  78. package/dist/types/coordinates.js.map +1 -0
  79. package/dist/types/errors.d.ts +94 -0
  80. package/dist/types/errors.d.ts.map +1 -0
  81. package/dist/types/errors.js +116 -0
  82. package/dist/types/errors.js.map +1 -0
  83. package/dist/types/forecasts.d.ts +49 -0
  84. package/dist/types/forecasts.d.ts.map +1 -0
  85. package/dist/types/forecasts.js +6 -0
  86. package/dist/types/forecasts.js.map +1 -0
  87. package/dist/types/hydro-stations.d.ts +143 -0
  88. package/dist/types/hydro-stations.d.ts.map +1 -0
  89. package/dist/types/hydro-stations.js +6 -0
  90. package/dist/types/hydro-stations.js.map +1 -0
  91. package/dist/types/index.d.ts +14 -0
  92. package/dist/types/index.d.ts.map +1 -0
  93. package/dist/types/index.js +9 -0
  94. package/dist/types/index.js.map +1 -0
  95. package/dist/types/places.d.ts +54 -0
  96. package/dist/types/places.d.ts.map +1 -0
  97. package/dist/types/places.js +6 -0
  98. package/dist/types/places.js.map +1 -0
  99. package/dist/types/stations.d.ts +90 -0
  100. package/dist/types/stations.d.ts.map +1 -0
  101. package/dist/types/stations.js +6 -0
  102. package/dist/types/stations.js.map +1 -0
  103. package/package.json +90 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @fileoverview Typed HTTP client with error handling and validation.
3
+ * @module meteo-lt-sdk/client/http
4
+ */
5
+ import { getGlobalRateLimiter } from './rate-limiter.js';
6
+ import { MeteoApiError, MeteoNotFoundError, MeteoRateLimitError, MeteoNetworkError, MeteoTimeoutError, MeteoValidationError, } from '../types/errors.js';
7
+ /**
8
+ * Internal HTTP client for making API requests.
9
+ * Handles error mapping, timeouts, and response validation.
10
+ */
11
+ export class HttpClient {
12
+ config;
13
+ constructor(config) {
14
+ this.config = config;
15
+ }
16
+ /**
17
+ * Makes a GET request and validates the response.
18
+ * @param path - API endpoint path (relative to base URL)
19
+ * @param schema - Zod schema for response validation
20
+ * @returns Validated and typed response data
21
+ * @throws {MeteoNotFoundError} When the resource is not found (404)
22
+ * @throws {MeteoRateLimitError} When rate limit is exceeded (429)
23
+ * @throws {MeteoApiError} For other HTTP errors
24
+ * @throws {MeteoNetworkError} For network failures
25
+ * @throws {MeteoTimeoutError} When request times out
26
+ * @throws {MeteoValidationError} When response doesn't match schema
27
+ */
28
+ async get(path, schema) {
29
+ // Always track requests with the global rate limiter for accurate counting.
30
+ // If throttling is enabled, wait for a slot; otherwise just record the request.
31
+ const rateLimiter = getGlobalRateLimiter();
32
+ if (this.config.throttle) {
33
+ await rateLimiter.acquire();
34
+ }
35
+ else {
36
+ rateLimiter.record();
37
+ }
38
+ const url = this.buildUrl(path);
39
+ const controller = new AbortController();
40
+ const timeoutId = setTimeout(() => { controller.abort(); }, this.config.timeout);
41
+ let response;
42
+ let responseText;
43
+ try {
44
+ response = await this.config.fetch(url, {
45
+ method: 'GET',
46
+ headers: {
47
+ 'Accept': 'application/json',
48
+ ...this.config.headers,
49
+ },
50
+ signal: controller.signal,
51
+ });
52
+ }
53
+ catch (error) {
54
+ clearTimeout(timeoutId);
55
+ if (error instanceof DOMException && error.name === 'AbortError') {
56
+ throw new MeteoTimeoutError(this.config.timeout);
57
+ }
58
+ const message = error instanceof Error ? error.message : 'Unknown network error';
59
+ throw new MeteoNetworkError(message, error instanceof Error ? error : undefined);
60
+ }
61
+ finally {
62
+ clearTimeout(timeoutId);
63
+ }
64
+ try {
65
+ responseText = await response.text();
66
+ }
67
+ catch {
68
+ responseText = '';
69
+ }
70
+ if (!response.ok) {
71
+ this.handleHttpError(response, responseText, path);
72
+ }
73
+ let data;
74
+ try {
75
+ data = JSON.parse(responseText);
76
+ }
77
+ catch {
78
+ throw new MeteoValidationError('Invalid JSON response', ['Response body is not valid JSON'], responseText);
79
+ }
80
+ const result = schema.safeParse(data);
81
+ if (!result.success) {
82
+ // Zod 4 uses 'issues' property
83
+ const errors = result.error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
84
+ throw new MeteoValidationError('Response validation failed', errors, responseText);
85
+ }
86
+ return result.data;
87
+ }
88
+ /**
89
+ * Builds full URL from path.
90
+ */
91
+ buildUrl(path) {
92
+ const baseUrl = this.config.baseUrl.endsWith('/')
93
+ ? this.config.baseUrl
94
+ : `${this.config.baseUrl}/`;
95
+ const cleanPath = path.startsWith('/') ? path.slice(1) : path;
96
+ return `${baseUrl}${cleanPath}`;
97
+ }
98
+ /**
99
+ * Maps HTTP error responses to specific error types.
100
+ */
101
+ handleHttpError(response, responseText, path) {
102
+ switch (response.status) {
103
+ case 404:
104
+ throw new MeteoNotFoundError(path, responseText);
105
+ case 429: {
106
+ const retryAfter = response.headers.get('Retry-After');
107
+ const retrySeconds = retryAfter !== null ? parseInt(retryAfter, 10) : undefined;
108
+ throw new MeteoRateLimitError(Number.isNaN(retrySeconds) ? undefined : retrySeconds, responseText);
109
+ }
110
+ default:
111
+ throw new MeteoApiError(`HTTP ${String(response.status)}: ${response.statusText}`, response.status, responseText);
112
+ }
113
+ }
114
+ }
115
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/client/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Client exports.
3
+ * @module meteo-lt-sdk/client
4
+ */
5
+ export { MeteoClient } from './MeteoClient.js';
6
+ export type { MeteoClientConfig, ResolvedMeteoClientConfig } from './config.js';
7
+ export { resolveConfig, DEFAULT_CONFIG } from './config.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Client exports.
3
+ * @module meteo-lt-sdk/client
4
+ */
5
+ export { MeteoClient } from './MeteoClient.js';
6
+ export { resolveConfig, DEFAULT_CONFIG } from './config.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @fileoverview Global rate limiter for API requests.
3
+ * @module meteo-lt-sdk/client/rate-limiter
4
+ */
5
+ /**
6
+ * Configuration for the rate limiter.
7
+ */
8
+ export interface RateLimiterConfig {
9
+ /** Maximum requests per window. Default: 180 */
10
+ readonly maxRequests: number;
11
+ /** Time window in milliseconds. Default: 60000 (1 minute) */
12
+ readonly windowMs: number;
13
+ }
14
+ /**
15
+ * A sliding window rate limiter that queues requests when limits are reached.
16
+ * Uses a global singleton pattern to track requests across all MeteoClient instances.
17
+ */
18
+ declare class RateLimiter {
19
+ private readonly timestamps;
20
+ private readonly config;
21
+ private readonly queue;
22
+ private processing;
23
+ constructor(config?: Partial<RateLimiterConfig>);
24
+ /**
25
+ * Acquires a slot to make a request.
26
+ * If the rate limit is reached, the request is queued and will be
27
+ * executed when a slot becomes available.
28
+ */
29
+ acquire(): Promise<void>;
30
+ /**
31
+ * Records a request without waiting for a slot.
32
+ * Used when throttling is disabled but we still want accurate tracking.
33
+ * This allows the rate limiter to have accurate counts even for non-throttled clients.
34
+ */
35
+ record(): void;
36
+ /**
37
+ * Processes queued requests when slots become available.
38
+ */
39
+ private processQueue;
40
+ private sleep;
41
+ /**
42
+ * Gets time until next available slot in milliseconds.
43
+ * Returns 0 if a slot is immediately available.
44
+ */
45
+ getTimeUntilAvailable(): number;
46
+ /**
47
+ * Gets current usage info.
48
+ */
49
+ getUsage(): {
50
+ current: number;
51
+ max: number;
52
+ windowMs: number;
53
+ };
54
+ }
55
+ /**
56
+ * Gets the global rate limiter instance, creating it if necessary.
57
+ */
58
+ export declare function getGlobalRateLimiter(): RateLimiter;
59
+ /**
60
+ * Resets the global rate limiter. Mainly useful for testing.
61
+ */
62
+ export declare function resetGlobalRateLimiter(): void;
63
+ export { RateLimiter };
64
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/client/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAOD;;;GAGG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAGb;IACT,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,GAAE,OAAO,CAAC,iBAAiB,CAAM;IAInD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAYd;;OAEG;YACW,YAAY;IAsC1B,OAAO,CAAC,KAAK;IAIb;;;OAGG;IACH,qBAAqB,IAAI,MAAM;IAmB/B;;OAEG;IACH,QAAQ,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAW/D;AASD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,WAAW,CAGlD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @fileoverview Global rate limiter for API requests.
3
+ * @module meteo-lt-sdk/client/rate-limiter
4
+ */
5
+ const DEFAULT_CONFIG = {
6
+ maxRequests: 180,
7
+ windowMs: 60000,
8
+ };
9
+ /**
10
+ * A sliding window rate limiter that queues requests when limits are reached.
11
+ * Uses a global singleton pattern to track requests across all MeteoClient instances.
12
+ */
13
+ class RateLimiter {
14
+ timestamps = [];
15
+ config;
16
+ queue = [];
17
+ processing = false;
18
+ constructor(config = {}) {
19
+ this.config = { ...DEFAULT_CONFIG, ...config };
20
+ }
21
+ /**
22
+ * Acquires a slot to make a request.
23
+ * If the rate limit is reached, the request is queued and will be
24
+ * executed when a slot becomes available.
25
+ */
26
+ async acquire() {
27
+ // Clean up old timestamps outside the window
28
+ const now = Date.now();
29
+ const windowStart = now - this.config.windowMs;
30
+ while (this.timestamps.length > 0 && this.timestamps[0] !== undefined && this.timestamps[0] < windowStart) {
31
+ this.timestamps.shift();
32
+ }
33
+ // Check if we can make a request immediately
34
+ if (this.timestamps.length < this.config.maxRequests) {
35
+ this.timestamps.push(now);
36
+ return;
37
+ }
38
+ // Queue the request and wait for a slot
39
+ return new Promise((resolve, reject) => {
40
+ this.queue.push({ resolve, reject });
41
+ void this.processQueue();
42
+ });
43
+ }
44
+ /**
45
+ * Records a request without waiting for a slot.
46
+ * Used when throttling is disabled but we still want accurate tracking.
47
+ * This allows the rate limiter to have accurate counts even for non-throttled clients.
48
+ */
49
+ record() {
50
+ const now = Date.now();
51
+ const windowStart = now - this.config.windowMs;
52
+ // Clean up old timestamps
53
+ while (this.timestamps.length > 0 && this.timestamps[0] !== undefined && this.timestamps[0] < windowStart) {
54
+ this.timestamps.shift();
55
+ }
56
+ this.timestamps.push(now);
57
+ }
58
+ /**
59
+ * Processes queued requests when slots become available.
60
+ */
61
+ async processQueue() {
62
+ if (this.processing || this.queue.length === 0) {
63
+ return;
64
+ }
65
+ this.processing = true;
66
+ while (this.queue.length > 0) {
67
+ const now = Date.now();
68
+ const windowStart = now - this.config.windowMs;
69
+ // Clean up old timestamps
70
+ while (this.timestamps.length > 0 && this.timestamps[0] !== undefined && this.timestamps[0] < windowStart) {
71
+ this.timestamps.shift();
72
+ }
73
+ // If we have room, process next in queue
74
+ if (this.timestamps.length < this.config.maxRequests) {
75
+ const next = this.queue.shift();
76
+ if (next !== undefined) {
77
+ this.timestamps.push(now);
78
+ next.resolve();
79
+ }
80
+ }
81
+ else {
82
+ // Wait until the oldest request expires from the window
83
+ const oldestTimestamp = this.timestamps[0];
84
+ if (oldestTimestamp !== undefined) {
85
+ const waitTime = oldestTimestamp - windowStart + 10; // +10ms buffer
86
+ await this.sleep(Math.max(waitTime, 10));
87
+ }
88
+ else {
89
+ await this.sleep(10);
90
+ }
91
+ }
92
+ }
93
+ this.processing = false;
94
+ }
95
+ sleep(ms) {
96
+ return new Promise(resolve => setTimeout(resolve, ms));
97
+ }
98
+ /**
99
+ * Gets time until next available slot in milliseconds.
100
+ * Returns 0 if a slot is immediately available.
101
+ */
102
+ getTimeUntilAvailable() {
103
+ const now = Date.now();
104
+ const windowStart = now - this.config.windowMs;
105
+ // Clean up old timestamps
106
+ const activeTimestamps = this.timestamps.filter(t => t >= windowStart);
107
+ if (activeTimestamps.length < this.config.maxRequests) {
108
+ return 0;
109
+ }
110
+ const oldestActive = activeTimestamps[0];
111
+ if (oldestActive === undefined) {
112
+ return 0;
113
+ }
114
+ return Math.max(0, oldestActive - windowStart);
115
+ }
116
+ /**
117
+ * Gets current usage info.
118
+ */
119
+ getUsage() {
120
+ const now = Date.now();
121
+ const windowStart = now - this.config.windowMs;
122
+ const current = this.timestamps.filter(t => t >= windowStart).length;
123
+ return {
124
+ current,
125
+ max: this.config.maxRequests,
126
+ windowMs: this.config.windowMs,
127
+ };
128
+ }
129
+ }
130
+ /**
131
+ * Global rate limiter instance shared across all MeteoClient instances.
132
+ * This ensures that even if multiple clients are created, they all
133
+ * respect the same rate limit (which is per-IP for the API).
134
+ */
135
+ let globalRateLimiter = null;
136
+ /**
137
+ * Gets the global rate limiter instance, creating it if necessary.
138
+ */
139
+ export function getGlobalRateLimiter() {
140
+ globalRateLimiter ??= new RateLimiter();
141
+ return globalRateLimiter;
142
+ }
143
+ /**
144
+ * Resets the global rate limiter. Mainly useful for testing.
145
+ */
146
+ export function resetGlobalRateLimiter() {
147
+ globalRateLimiter = null;
148
+ }
149
+ export { RateLimiter };
150
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/client/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @fileoverview Meteo.lt TypeScript SDK
3
+ *
4
+ * Production-grade SDK for the Lithuanian Hydrometeorological Service (LHMT) API.
5
+ * Provides type-safe access to weather forecasts, meteorological observations,
6
+ * and hydrological data.
7
+ *
8
+ * @packageDocumentation
9
+ * @module meteo-lt-sdk
10
+ *
11
+ * @example Basic usage
12
+ * ```typescript
13
+ * import { MeteoClient } from 'meteo-lt-sdk';
14
+ *
15
+ * const client = new MeteoClient();
16
+ *
17
+ * // Get weather forecast
18
+ * const forecast = await client.places.getForecast('vilnius', 'long-term');
19
+ *
20
+ * // Get station observations
21
+ * const observations = await client.stations.getObservations('vilniaus-ams', 'latest');
22
+ *
23
+ * // Get hydro data
24
+ * const hydroData = await client.hydroStations.getMeasuredObservations('nemajunu-vms', 'latest');
25
+ * ```
26
+ */
27
+ export { MeteoClient } from './client/MeteoClient.js';
28
+ export type { MeteoClientConfig, ResolvedMeteoClientConfig } from './client/config.js';
29
+ export { PlacesApi } from './api/places.js';
30
+ export { StationsApi } from './api/stations.js';
31
+ export { HydroStationsApi } from './api/hydro-stations.js';
32
+ export type { Latitude, Longitude, Coordinates, ForecastConditionCode, ObservationConditionCode, PlaceSummary, PlaceDetails, ForecastType, ForecastTypeInfo, PlaceForecastTypes, ForecastTimestamp, Forecast, StationSummary, StationDetails, ObservationsDataRange, StationObservationsInfo, Observation, StationObservations, ObservationDateParam, HydroStationSummary, HydroStationDetails, HydroObservationType, HydroObservationTypeInfo, HydroStationObservationTypes, MeasuredDataRange, HistoricalDataRange, HydroStationMeasuredInfo, HydroStationHistoricalInfo, MeasuredHydroObservation, HistoricalHydroObservation, HydroStationMeasuredObservations, HydroStationHistoricalObservations, MeasuredDateParam, HistoricalDateParam, } from './types/index.js';
33
+ export { MeteoApiError, MeteoNotFoundError, MeteoRateLimitError, MeteoValidationError, MeteoNetworkError, MeteoTimeoutError, } from './types/errors.js';
34
+ export { isValidLatitude, isValidLongitude, createLatitude, createLongitude, createCoordinates, FORECAST_CONDITION_CODES, OBSERVATION_CONDITION_CODES, CONDITION_DESCRIPTIONS, isForecastConditionCode, isObservationConditionCode, getConditionDescription, } from './types/index.js';
35
+ export * as schemas from './schemas/index.js';
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,YAAY,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGvF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,YAAY,EAEV,QAAQ,EACR,SAAS,EACT,WAAW,EAEX,qBAAqB,EACrB,wBAAwB,EAExB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAElB,iBAAiB,EACjB,QAAQ,EAER,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EAEpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,4BAA4B,EAC5B,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,gCAAgC,EAChC,kCAAkC,EAClC,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAEL,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB,EAEjB,wBAAwB,EACxB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @fileoverview Meteo.lt TypeScript SDK
3
+ *
4
+ * Production-grade SDK for the Lithuanian Hydrometeorological Service (LHMT) API.
5
+ * Provides type-safe access to weather forecasts, meteorological observations,
6
+ * and hydrological data.
7
+ *
8
+ * @packageDocumentation
9
+ * @module meteo-lt-sdk
10
+ *
11
+ * @example Basic usage
12
+ * ```typescript
13
+ * import { MeteoClient } from 'meteo-lt-sdk';
14
+ *
15
+ * const client = new MeteoClient();
16
+ *
17
+ * // Get weather forecast
18
+ * const forecast = await client.places.getForecast('vilnius', 'long-term');
19
+ *
20
+ * // Get station observations
21
+ * const observations = await client.stations.getObservations('vilniaus-ams', 'latest');
22
+ *
23
+ * // Get hydro data
24
+ * const hydroData = await client.hydroStations.getMeasuredObservations('nemajunu-vms', 'latest');
25
+ * ```
26
+ */
27
+ // Main client
28
+ export { MeteoClient } from './client/MeteoClient.js';
29
+ // API modules for advanced usage
30
+ export { PlacesApi } from './api/places.js';
31
+ export { StationsApi } from './api/stations.js';
32
+ export { HydroStationsApi } from './api/hydro-stations.js';
33
+ // Error classes
34
+ export { MeteoApiError, MeteoNotFoundError, MeteoRateLimitError, MeteoValidationError, MeteoNetworkError, MeteoTimeoutError, } from './types/errors.js';
35
+ // Utility exports
36
+ export {
37
+ // Coordinate utilities
38
+ isValidLatitude, isValidLongitude, createLatitude, createLongitude, createCoordinates,
39
+ // Condition utilities
40
+ FORECAST_CONDITION_CODES, OBSERVATION_CONDITION_CODES, CONDITION_DESCRIPTIONS, isForecastConditionCode, isObservationConditionCode, getConditionDescription, } from './types/index.js';
41
+ // Schema exports for advanced validation
42
+ export * as schemas from './schemas/index.js';
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,cAAc;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,iCAAiC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AA8C3D,gBAAgB;AAChB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,kBAAkB;AAClB,OAAO;AACL,uBAAuB;AACvB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB;AACjB,sBAAsB;AACtB,wBAAwB,EACxB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAE1B,yCAAyC;AACzC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview Zod schemas for coordinate validation.
3
+ * @module meteo-lt-sdk/schemas/coordinates
4
+ */
5
+ import { z } from 'zod';
6
+ import type { Latitude, Longitude } from '../types/coordinates.js';
7
+ /**
8
+ * Schema for latitude values in decimal degrees.
9
+ * Validates that the value is between -90 and 90.
10
+ */
11
+ export declare const latitudeSchema: z.ZodPipe<z.ZodNumber, z.ZodTransform<Latitude, number>>;
12
+ /**
13
+ * Schema for longitude values in decimal degrees.
14
+ * Validates that the value is between -180 and 180.
15
+ */
16
+ export declare const longitudeSchema: z.ZodPipe<z.ZodNumber, z.ZodTransform<Longitude, number>>;
17
+ /**
18
+ * Schema for geographic coordinates.
19
+ * Validates and transforms to the Coordinates type with branded lat/lng.
20
+ */
21
+ export declare const coordinatesSchema: z.ZodObject<{
22
+ latitude: z.ZodPipe<z.ZodNumber, z.ZodTransform<Latitude, number>>;
23
+ longitude: z.ZodPipe<z.ZodNumber, z.ZodTransform<Longitude, number>>;
24
+ }, z.core.$strip>;
25
+ export type CoordinatesInput = z.input<typeof coordinatesSchema>;
26
+ //# sourceMappingURL=coordinates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinates.d.ts","sourceRoot":"","sources":["../../src/schemas/coordinates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAe,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEhF;;;GAGG;AACH,eAAO,MAAM,cAAc,0DAIqB,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,eAAe,2DAIsB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;iBAGK,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview Zod schemas for coordinate validation.
3
+ * @module meteo-lt-sdk/schemas/coordinates
4
+ */
5
+ import { z } from 'zod';
6
+ /**
7
+ * Schema for latitude values in decimal degrees.
8
+ * Validates that the value is between -90 and 90.
9
+ */
10
+ export const latitudeSchema = z
11
+ .number()
12
+ .min(-90, 'Latitude must be at least -90')
13
+ .max(90, 'Latitude must be at most 90')
14
+ .transform((val) => val);
15
+ /**
16
+ * Schema for longitude values in decimal degrees.
17
+ * Validates that the value is between -180 and 180.
18
+ */
19
+ export const longitudeSchema = z
20
+ .number()
21
+ .min(-180, 'Longitude must be at least -180')
22
+ .max(180, 'Longitude must be at most 180')
23
+ .transform((val) => val);
24
+ /**
25
+ * Schema for geographic coordinates.
26
+ * Validates and transforms to the Coordinates type with branded lat/lng.
27
+ */
28
+ export const coordinatesSchema = z.object({
29
+ latitude: latitudeSchema,
30
+ longitude: longitudeSchema,
31
+ });
32
+ //# sourceMappingURL=coordinates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinates.js","sourceRoot":"","sources":["../../src/schemas/coordinates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,EAAE,+BAA+B,CAAC;KACzC,GAAG,CAAC,EAAE,EAAE,6BAA6B,CAAC;KACtC,SAAS,CAAC,CAAC,GAAG,EAAY,EAAE,CAAC,GAAe,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC;KAC7B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,GAAG,EAAE,iCAAiC,CAAC;KAC5C,GAAG,CAAC,GAAG,EAAE,+BAA+B,CAAC;KACzC,SAAS,CAAC,CAAC,GAAG,EAAa,EAAE,CAAC,GAAgB,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,cAAc;IACxB,SAAS,EAAE,eAAe;CAC3B,CAAkC,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @fileoverview Zod schemas for forecast data validation.
3
+ * @module meteo-lt-sdk/schemas/forecasts
4
+ */
5
+ import { z } from 'zod';
6
+ /**
7
+ * Schema for a single forecast timestamp.
8
+ */
9
+ export declare const forecastTimestampSchema: z.ZodObject<{
10
+ forecastTimeUtc: z.ZodString;
11
+ airTemperature: z.ZodNumber;
12
+ feelsLikeTemperature: z.ZodNumber;
13
+ windSpeed: z.ZodNumber;
14
+ windGust: z.ZodNumber;
15
+ windDirection: z.ZodNumber;
16
+ cloudCover: z.ZodNumber;
17
+ seaLevelPressure: z.ZodNumber;
18
+ relativeHumidity: z.ZodNumber;
19
+ totalPrecipitation: z.ZodNumber;
20
+ conditionCode: z.ZodNullable<z.ZodEnum<{
21
+ clear: "clear";
22
+ "partly-cloudy": "partly-cloudy";
23
+ "cloudy-with-sunny-intervals": "cloudy-with-sunny-intervals";
24
+ cloudy: "cloudy";
25
+ "light-rain": "light-rain";
26
+ rain: "rain";
27
+ "heavy-rain": "heavy-rain";
28
+ thunder: "thunder";
29
+ "isolated-thunderstorms": "isolated-thunderstorms";
30
+ thunderstorms: "thunderstorms";
31
+ "heavy-rain-with-thunderstorms": "heavy-rain-with-thunderstorms";
32
+ "light-sleet": "light-sleet";
33
+ sleet: "sleet";
34
+ "freezing-rain": "freezing-rain";
35
+ hail: "hail";
36
+ "light-snow": "light-snow";
37
+ snow: "snow";
38
+ "heavy-snow": "heavy-snow";
39
+ fog: "fog";
40
+ }>>;
41
+ }, z.core.$strip>;
42
+ /**
43
+ * Schema for a complete forecast response.
44
+ */
45
+ export declare const forecastSchema: z.ZodObject<{
46
+ place: z.ZodObject<{
47
+ code: z.ZodString;
48
+ name: z.ZodString;
49
+ administrativeDivision: z.ZodString;
50
+ countryCode: z.ZodString;
51
+ coordinates: z.ZodObject<{
52
+ latitude: z.ZodPipe<z.ZodNumber, z.ZodTransform<import("../index.js").Latitude, number>>;
53
+ longitude: z.ZodPipe<z.ZodNumber, z.ZodTransform<import("../index.js").Longitude, number>>;
54
+ }, z.core.$strip>;
55
+ country: z.ZodString;
56
+ }, z.core.$strip>;
57
+ forecastType: z.ZodLiteral<"long-term">;
58
+ forecastCreationTimeUtc: z.ZodString;
59
+ forecastTimestamps: z.ZodArray<z.ZodObject<{
60
+ forecastTimeUtc: z.ZodString;
61
+ airTemperature: z.ZodNumber;
62
+ feelsLikeTemperature: z.ZodNumber;
63
+ windSpeed: z.ZodNumber;
64
+ windGust: z.ZodNumber;
65
+ windDirection: z.ZodNumber;
66
+ cloudCover: z.ZodNumber;
67
+ seaLevelPressure: z.ZodNumber;
68
+ relativeHumidity: z.ZodNumber;
69
+ totalPrecipitation: z.ZodNumber;
70
+ conditionCode: z.ZodNullable<z.ZodEnum<{
71
+ clear: "clear";
72
+ "partly-cloudy": "partly-cloudy";
73
+ "cloudy-with-sunny-intervals": "cloudy-with-sunny-intervals";
74
+ cloudy: "cloudy";
75
+ "light-rain": "light-rain";
76
+ rain: "rain";
77
+ "heavy-rain": "heavy-rain";
78
+ thunder: "thunder";
79
+ "isolated-thunderstorms": "isolated-thunderstorms";
80
+ thunderstorms: "thunderstorms";
81
+ "heavy-rain-with-thunderstorms": "heavy-rain-with-thunderstorms";
82
+ "light-sleet": "light-sleet";
83
+ sleet: "sleet";
84
+ "freezing-rain": "freezing-rain";
85
+ hail: "hail";
86
+ "light-snow": "light-snow";
87
+ snow: "snow";
88
+ "heavy-snow": "heavy-snow";
89
+ fog: "fog";
90
+ }>>;
91
+ }, z.core.$strip>>;
92
+ }, z.core.$strip>;
93
+ //# sourceMappingURL=forecasts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forecasts.d.ts","sourceRoot":"","sources":["../../src/schemas/forecasts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAYK,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKK,CAAC"}