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.
- package/LICENSE +21 -0
- package/README.md +280 -0
- package/dist/__tests__/test-utils.d.ts +240 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/__tests__/test-utils.js +278 -0
- package/dist/__tests__/test-utils.js.map +1 -0
- package/dist/api/hydro-stations.d.ts +133 -0
- package/dist/api/hydro-stations.d.ts.map +1 -0
- package/dist/api/hydro-stations.js +148 -0
- package/dist/api/hydro-stations.js.map +1 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +8 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/places.d.ts +78 -0
- package/dist/api/places.d.ts.map +1 -0
- package/dist/api/places.js +87 -0
- package/dist/api/places.js.map +1 -0
- package/dist/api/stations.d.ts +80 -0
- package/dist/api/stations.d.ts.map +1 -0
- package/dist/api/stations.js +89 -0
- package/dist/api/stations.js.map +1 -0
- package/dist/client/MeteoClient.d.ts +85 -0
- package/dist/client/MeteoClient.d.ts.map +1 -0
- package/dist/client/MeteoClient.js +92 -0
- package/dist/client/MeteoClient.js.map +1 -0
- package/dist/client/config.d.ts +57 -0
- package/dist/client/config.d.ts.map +1 -0
- package/dist/client/config.js +29 -0
- package/dist/client/config.js.map +1 -0
- package/dist/client/http.d.ts +36 -0
- package/dist/client/http.d.ts.map +1 -0
- package/dist/client/http.js +115 -0
- package/dist/client/http.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/rate-limiter.d.ts +64 -0
- package/dist/client/rate-limiter.d.ts.map +1 -0
- package/dist/client/rate-limiter.js +150 -0
- package/dist/client/rate-limiter.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/coordinates.d.ts +26 -0
- package/dist/schemas/coordinates.d.ts.map +1 -0
- package/dist/schemas/coordinates.js +32 -0
- package/dist/schemas/coordinates.js.map +1 -0
- package/dist/schemas/forecasts.d.ts +93 -0
- package/dist/schemas/forecasts.d.ts.map +1 -0
- package/dist/schemas/forecasts.js +38 -0
- package/dist/schemas/forecasts.js.map +1 -0
- package/dist/schemas/hydro-stations.d.ts +172 -0
- package/dist/schemas/hydro-stations.d.ts.map +1 -0
- package/dist/schemas/hydro-stations.js +99 -0
- package/dist/schemas/hydro-stations.js.map +1 -0
- package/dist/schemas/index.d.ts +10 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +15 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/places.d.ts +77 -0
- package/dist/schemas/places.d.ts.map +1 -0
- package/dist/schemas/places.js +45 -0
- package/dist/schemas/places.js.map +1 -0
- package/dist/schemas/stations.d.ts +167 -0
- package/dist/schemas/stations.d.ts.map +1 -0
- package/dist/schemas/stations.js +69 -0
- package/dist/schemas/stations.js.map +1 -0
- package/dist/types/conditions.d.ts +47 -0
- package/dist/types/conditions.d.ts.map +1 -0
- package/dist/types/conditions.js +132 -0
- package/dist/types/conditions.js.map +1 -0
- package/dist/types/coordinates.d.ts +63 -0
- package/dist/types/coordinates.d.ts.map +1 -0
- package/dist/types/coordinates.js +58 -0
- package/dist/types/coordinates.js.map +1 -0
- package/dist/types/errors.d.ts +94 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +116 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/forecasts.d.ts +49 -0
- package/dist/types/forecasts.d.ts.map +1 -0
- package/dist/types/forecasts.js +6 -0
- package/dist/types/forecasts.js.map +1 -0
- package/dist/types/hydro-stations.d.ts +143 -0
- package/dist/types/hydro-stations.d.ts.map +1 -0
- package/dist/types/hydro-stations.js +6 -0
- package/dist/types/hydro-stations.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/places.d.ts +54 -0
- package/dist/types/places.d.ts.map +1 -0
- package/dist/types/places.js +6 -0
- package/dist/types/places.js.map +1 -0
- package/dist/types/stations.d.ts +90 -0
- package/dist/types/stations.d.ts.map +1 -0
- package/dist/types/stations.js +6 -0
- package/dist/types/stations.js.map +1 -0
- 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 @@
|
|
|
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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|