@mharj/openweathermap 0.0.1
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/README.md +7 -0
- package/dist/OpenWeatherV2.d.ts +108 -0
- package/dist/OpenWeatherV2.js +174 -0
- package/dist/OpenWeatherV2.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/IOpenWeatherV2.d.ts +7 -0
- package/dist/interfaces/IOpenWeatherV2.js +3 -0
- package/dist/interfaces/IOpenWeatherV2.js.map +1 -0
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.js +5 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/lib/fetchUtils.d.ts +5 -0
- package/dist/lib/fetchUtils.js +17 -0
- package/dist/lib/fetchUtils.js.map +1 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +5 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/types/ISO3166-Countries.d.ts +7 -0
- package/dist/types/ISO3166-Countries.js +260 -0
- package/dist/types/ISO3166-Countries.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/v2/Icon.d.ts +17 -0
- package/dist/types/v2/Icon.js +19 -0
- package/dist/types/v2/Icon.js.map +1 -0
- package/dist/types/v2/Language.d.ts +4 -0
- package/dist/types/v2/Language.js +53 -0
- package/dist/types/v2/Language.js.map +1 -0
- package/dist/types/v2/index.d.ts +229 -0
- package/dist/types/v2/index.js +80 -0
- package/dist/types/v2/index.js.map +1 -0
- package/dist/types/v2/weatherIdGroup.d.ts +262 -0
- package/dist/types/v2/weatherIdGroup.js +317 -0
- package/dist/types/v2/weatherIdGroup.js.map +1 -0
- package/package.json +89 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { CountryCode, LangCode, Loadable, WeatherDataV2 } from './types';
|
|
2
|
+
import { Result } from 'mharj-result';
|
|
3
|
+
import type { ICacheOrAsync } from '@avanio/expire-cache';
|
|
4
|
+
import type { IOpenWeatherV2 } from './interfaces/IOpenWeatherV2';
|
|
5
|
+
/**
|
|
6
|
+
* Open Weather V2 API Common Options
|
|
7
|
+
* @default {lang: 'en', units: 'standard'} in API
|
|
8
|
+
* @example
|
|
9
|
+
* {lang: 'fi', units: 'metric'}
|
|
10
|
+
*/
|
|
11
|
+
export type OpenWeatherV2CommonOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* Language code
|
|
14
|
+
*/
|
|
15
|
+
lang?: LangCode;
|
|
16
|
+
/**
|
|
17
|
+
* Weather units
|
|
18
|
+
*/
|
|
19
|
+
units?: 'standard' | 'metric' | 'imperial';
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Open Weather V2 API
|
|
23
|
+
* @example
|
|
24
|
+
* const weather = new OpenWeatherV2('your-api-key');
|
|
25
|
+
*
|
|
26
|
+
* const cache = new ExpireCache<WeatherDataV2>(undefined, undefined, 900000); // data 15 minutes in cache
|
|
27
|
+
* const weather = new OpenWeatherV2(() => Promise.resolve('your-api-key'), cache);
|
|
28
|
+
*
|
|
29
|
+
* const data: WeatherDataV2 = (await weather.getWeatherById(2643743)).unwrap(); // throws if error
|
|
30
|
+
* const data: WeatherDataV2 | undefined = (await weather.getWeatherByCity('Helsinki', 'fi')).ok();
|
|
31
|
+
*
|
|
32
|
+
* const result: Result<WeatherDataV2> = await weather.getWeatherByLatLon(60.1699, 24.9384);
|
|
33
|
+
* result.match({
|
|
34
|
+
* Ok: (data: WeatherDataV2) => console.log(data),
|
|
35
|
+
* Err: (err: DOMException | TypeError) => console.error(err),
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* if(result.isOk) {
|
|
39
|
+
* const data: WeatherDataV2 = data.ok();
|
|
40
|
+
* } else {
|
|
41
|
+
* const err: DOMException | TypeError = data.err();
|
|
42
|
+
* }
|
|
43
|
+
*/
|
|
44
|
+
export declare class OpenWeatherV2 {
|
|
45
|
+
private cache;
|
|
46
|
+
private loadableApiKey;
|
|
47
|
+
private apiHandler;
|
|
48
|
+
/**
|
|
49
|
+
* OpenWeatherV2 constructor
|
|
50
|
+
* @param {Loadable<string>} loadableApiKey - Loadable API key
|
|
51
|
+
* @param {ICacheOrAsync<WeatherDataV2>=} cache - optional async cache implementation
|
|
52
|
+
* @param {IOpenWeatherV2=} apiHandler - optional API handler implementation for mocking
|
|
53
|
+
*/
|
|
54
|
+
constructor(loadableApiKey: Loadable<string>, cache?: ICacheOrAsync<WeatherDataV2>, apiHandler?: IOpenWeatherV2);
|
|
55
|
+
/**
|
|
56
|
+
* get weather by Id
|
|
57
|
+
* @param {number} id - Weather station ID
|
|
58
|
+
* @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
|
|
59
|
+
* @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
|
|
60
|
+
* @example
|
|
61
|
+
* const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherResultById(id: 564, {lang: 'fi'});
|
|
62
|
+
* if (result.isOk) {
|
|
63
|
+
* const weatherData: WeatherDataV2 = result.ok();
|
|
64
|
+
* } else {
|
|
65
|
+
* const error: DOMException | TypeError = result.err();
|
|
66
|
+
* }
|
|
67
|
+
*/
|
|
68
|
+
getWeatherById(id: number, opts?: OpenWeatherV2CommonOptions): Promise<Result<WeatherDataV2, DOMException | TypeError>>;
|
|
69
|
+
/**
|
|
70
|
+
* get weather with city name and optional country code
|
|
71
|
+
* @param {string} city - City name
|
|
72
|
+
* @param {countryCode=} countryCode - Optional Country code
|
|
73
|
+
* @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
|
|
74
|
+
* @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
|
|
75
|
+
* @example
|
|
76
|
+
* const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByCity('Helsinki', 'fi', {lang: 'fi'});
|
|
77
|
+
* if (result.isOk) {
|
|
78
|
+
* const weatherData: WeatherDataV2 = result.ok();
|
|
79
|
+
* } else {
|
|
80
|
+
* const error: DOMException | TypeError = result.err();
|
|
81
|
+
* }
|
|
82
|
+
*/
|
|
83
|
+
getWeatherByCity(city: string, countryCode?: CountryCode, opts?: OpenWeatherV2CommonOptions): Promise<Result<WeatherDataV2, DOMException | TypeError>>;
|
|
84
|
+
/**
|
|
85
|
+
* get weather with latitude and longitude with Result
|
|
86
|
+
* @param {number} lat - Latitude
|
|
87
|
+
* @param {number} lon - Longitude
|
|
88
|
+
* @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
|
|
89
|
+
* @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
|
|
90
|
+
* @example
|
|
91
|
+
* const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByLatLon(60.1699, 24.9384, {lang: 'fi'});
|
|
92
|
+
* if (result.isOk) {
|
|
93
|
+
* const weatherData: WeatherDataV2 = result.ok();
|
|
94
|
+
* } else {
|
|
95
|
+
* const error: DOMException | TypeError = result.err();
|
|
96
|
+
* }
|
|
97
|
+
*/
|
|
98
|
+
getWeatherByLatLon(lat: number, lon: number, opts?: OpenWeatherV2CommonOptions): Promise<Result<WeatherDataV2, DOMException | TypeError>>;
|
|
99
|
+
private buildBaseParams;
|
|
100
|
+
/**
|
|
101
|
+
* build base cache key
|
|
102
|
+
* @param main - main cache key prefix
|
|
103
|
+
* @param opts - OpenWeatherV2CommonOptions
|
|
104
|
+
* @returns {CacheKey}
|
|
105
|
+
*/
|
|
106
|
+
private buildBaseCacheKey;
|
|
107
|
+
private handleFetch;
|
|
108
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenWeatherV2 = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const mharj_result_1 = require("mharj-result");
|
|
6
|
+
const fetchUtils_1 = require("./lib/fetchUtils");
|
|
7
|
+
const defaultImplementation = {
|
|
8
|
+
dataWeatherApi: async (params) => {
|
|
9
|
+
const resp = await fetch(`https://api.openweathermap.org/data/2.5/weather?${params.toString()}`);
|
|
10
|
+
if (!resp.ok) {
|
|
11
|
+
throw new Error(resp.statusText);
|
|
12
|
+
}
|
|
13
|
+
const data = (await resp.json());
|
|
14
|
+
(0, types_1.assertWeatherDataV2)(data);
|
|
15
|
+
return data;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Open Weather V2 API
|
|
20
|
+
* @example
|
|
21
|
+
* const weather = new OpenWeatherV2('your-api-key');
|
|
22
|
+
*
|
|
23
|
+
* const cache = new ExpireCache<WeatherDataV2>(undefined, undefined, 900000); // data 15 minutes in cache
|
|
24
|
+
* const weather = new OpenWeatherV2(() => Promise.resolve('your-api-key'), cache);
|
|
25
|
+
*
|
|
26
|
+
* const data: WeatherDataV2 = (await weather.getWeatherById(2643743)).unwrap(); // throws if error
|
|
27
|
+
* const data: WeatherDataV2 | undefined = (await weather.getWeatherByCity('Helsinki', 'fi')).ok();
|
|
28
|
+
*
|
|
29
|
+
* const result: Result<WeatherDataV2> = await weather.getWeatherByLatLon(60.1699, 24.9384);
|
|
30
|
+
* result.match({
|
|
31
|
+
* Ok: (data: WeatherDataV2) => console.log(data),
|
|
32
|
+
* Err: (err: DOMException | TypeError) => console.error(err),
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* if(result.isOk) {
|
|
36
|
+
* const data: WeatherDataV2 = data.ok();
|
|
37
|
+
* } else {
|
|
38
|
+
* const err: DOMException | TypeError = data.err();
|
|
39
|
+
* }
|
|
40
|
+
*/
|
|
41
|
+
class OpenWeatherV2 {
|
|
42
|
+
cache;
|
|
43
|
+
loadableApiKey;
|
|
44
|
+
apiHandler;
|
|
45
|
+
/**
|
|
46
|
+
* OpenWeatherV2 constructor
|
|
47
|
+
* @param {Loadable<string>} loadableApiKey - Loadable API key
|
|
48
|
+
* @param {ICacheOrAsync<WeatherDataV2>=} cache - optional async cache implementation
|
|
49
|
+
* @param {IOpenWeatherV2=} apiHandler - optional API handler implementation for mocking
|
|
50
|
+
*/
|
|
51
|
+
constructor(loadableApiKey, cache, apiHandler = defaultImplementation) {
|
|
52
|
+
this.loadableApiKey = loadableApiKey;
|
|
53
|
+
this.cache = cache;
|
|
54
|
+
this.apiHandler = apiHandler;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* get weather by Id
|
|
58
|
+
* @param {number} id - Weather station ID
|
|
59
|
+
* @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
|
|
60
|
+
* @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
|
|
61
|
+
* @example
|
|
62
|
+
* const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherResultById(id: 564, {lang: 'fi'});
|
|
63
|
+
* if (result.isOk) {
|
|
64
|
+
* const weatherData: WeatherDataV2 = result.ok();
|
|
65
|
+
* } else {
|
|
66
|
+
* const error: DOMException | TypeError = result.err();
|
|
67
|
+
* }
|
|
68
|
+
*/
|
|
69
|
+
async getWeatherById(id, opts = {}) {
|
|
70
|
+
try {
|
|
71
|
+
const cacheKey = this.buildBaseCacheKey(`id:${id}`, opts);
|
|
72
|
+
let cacheEntry = this.cache && (await this.cache.get(cacheKey));
|
|
73
|
+
if (!cacheEntry) {
|
|
74
|
+
const params = await this.buildBaseParams(opts);
|
|
75
|
+
params.append('id', String(id));
|
|
76
|
+
cacheEntry = await this.handleFetch(cacheKey, params, opts);
|
|
77
|
+
}
|
|
78
|
+
return (0, mharj_result_1.Ok)(cacheEntry);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return (0, mharj_result_1.Err)((0, fetchUtils_1.fetchErrorWrapper)(err));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* get weather with city name and optional country code
|
|
86
|
+
* @param {string} city - City name
|
|
87
|
+
* @param {countryCode=} countryCode - Optional Country code
|
|
88
|
+
* @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
|
|
89
|
+
* @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
|
|
90
|
+
* @example
|
|
91
|
+
* const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByCity('Helsinki', 'fi', {lang: 'fi'});
|
|
92
|
+
* if (result.isOk) {
|
|
93
|
+
* const weatherData: WeatherDataV2 = result.ok();
|
|
94
|
+
* } else {
|
|
95
|
+
* const error: DOMException | TypeError = result.err();
|
|
96
|
+
* }
|
|
97
|
+
*/
|
|
98
|
+
async getWeatherByCity(city, countryCode, opts = {}) {
|
|
99
|
+
try {
|
|
100
|
+
const cacheKey = this.buildBaseCacheKey(`q:${city}:${countryCode}`, opts);
|
|
101
|
+
let cacheEntry = this.cache && (await this.cache.get(cacheKey));
|
|
102
|
+
if (!cacheEntry) {
|
|
103
|
+
const params = await this.buildBaseParams(opts);
|
|
104
|
+
params.append('q', countryCode ? `${city},${countryCode}` : city);
|
|
105
|
+
cacheEntry = await this.handleFetch(cacheKey, params, opts);
|
|
106
|
+
}
|
|
107
|
+
return (0, mharj_result_1.Ok)(cacheEntry);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
return (0, mharj_result_1.Err)((0, fetchUtils_1.fetchErrorWrapper)(err));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* get weather with latitude and longitude with Result
|
|
115
|
+
* @param {number} lat - Latitude
|
|
116
|
+
* @param {number} lon - Longitude
|
|
117
|
+
* @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
|
|
118
|
+
* @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
|
|
119
|
+
* @example
|
|
120
|
+
* const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByLatLon(60.1699, 24.9384, {lang: 'fi'});
|
|
121
|
+
* if (result.isOk) {
|
|
122
|
+
* const weatherData: WeatherDataV2 = result.ok();
|
|
123
|
+
* } else {
|
|
124
|
+
* const error: DOMException | TypeError = result.err();
|
|
125
|
+
* }
|
|
126
|
+
*/
|
|
127
|
+
async getWeatherByLatLon(lat, lon, opts = {}) {
|
|
128
|
+
try {
|
|
129
|
+
const cacheKey = this.buildBaseCacheKey(`latlon:${lat}:${lon}`, opts);
|
|
130
|
+
let cacheEntry = this.cache && (await this.cache.get(cacheKey));
|
|
131
|
+
if (!cacheEntry) {
|
|
132
|
+
const params = await this.buildBaseParams(opts);
|
|
133
|
+
params.append('lat', String(lat));
|
|
134
|
+
params.append('lon', String(lon));
|
|
135
|
+
cacheEntry = await this.handleFetch(cacheKey, params, opts);
|
|
136
|
+
}
|
|
137
|
+
return (0, mharj_result_1.Ok)(cacheEntry);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
return (0, mharj_result_1.Err)((0, fetchUtils_1.fetchErrorWrapper)(err));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async buildBaseParams({ lang, units }) {
|
|
144
|
+
const apiKey = await (typeof this.loadableApiKey === 'function' ? this.loadableApiKey() : this.loadableApiKey);
|
|
145
|
+
const params = new URLSearchParams();
|
|
146
|
+
lang && params.append('lang', lang);
|
|
147
|
+
units && params.append('units', units);
|
|
148
|
+
params.append('appid', apiKey);
|
|
149
|
+
return params;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* build base cache key
|
|
153
|
+
* @param main - main cache key prefix
|
|
154
|
+
* @param opts - OpenWeatherV2CommonOptions
|
|
155
|
+
* @returns {CacheKey}
|
|
156
|
+
*/
|
|
157
|
+
buildBaseCacheKey(main, { lang, units }) {
|
|
158
|
+
return `${main}:${lang}:${units}`;
|
|
159
|
+
}
|
|
160
|
+
async handleFetch(cacheKey, params, opts) {
|
|
161
|
+
const data = await this.apiHandler.dataWeatherApi(params);
|
|
162
|
+
(0, types_1.assertWeatherDataV2)(data);
|
|
163
|
+
if (this.cache) {
|
|
164
|
+
await this.cache.set(cacheKey, data);
|
|
165
|
+
if (!cacheKey.startsWith('id:')) {
|
|
166
|
+
// update id cache too
|
|
167
|
+
await this.cache.set(this.buildBaseCacheKey(`id:${data.id}`, opts), data);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return data;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.OpenWeatherV2 = OpenWeatherV2;
|
|
174
|
+
//# sourceMappingURL=OpenWeatherV2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenWeatherV2.js","sourceRoot":"./src/","sources":["OpenWeatherV2.ts"],"names":[],"mappings":"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","sourcesContent":["import {assertWeatherDataV2, CountryCode, LangCode, Loadable, WeatherDataV2} from './types';\nimport {Err, Ok, Result} from 'mharj-result';\nimport {fetchErrorWrapper} from './lib/fetchUtils';\nimport type {ICacheOrAsync} from '@avanio/expire-cache';\nimport type {IOpenWeatherV2} from './interfaces/IOpenWeatherV2';\n\n/**\n * Open Weather V2 API Common Options\n * @default {lang: 'en', units: 'standard'} in API\n * @example\n * {lang: 'fi', units: 'metric'}\n */\nexport type OpenWeatherV2CommonOptions = {\n\t/**\n\t * Language code\n\t */\n\tlang?: LangCode;\n\t/**\n\t * Weather units\n\t */\n\tunits?: 'standard' | 'metric' | 'imperial';\n};\n\nconst defaultImplementation: IOpenWeatherV2 = {\n\tdataWeatherApi: async (params: URLSearchParams): Promise<WeatherDataV2> => {\n\t\tconst resp = await fetch(`https://api.openweathermap.org/data/2.5/weather?${params.toString()}`);\n\t\tif (!resp.ok) {\n\t\t\tthrow new Error(resp.statusText);\n\t\t}\n\t\tconst data = (await resp.json()) as unknown;\n\t\tassertWeatherDataV2(data);\n\t\treturn data;\n\t},\n};\n\n/**\n * Open Weather V2 API\n * @example\n * const weather = new OpenWeatherV2('your-api-key');\n *\n * const cache = new ExpireCache<WeatherDataV2>(undefined, undefined, 900000); // data 15 minutes in cache\n * const weather = new OpenWeatherV2(() => Promise.resolve('your-api-key'), cache);\n *\n * const data: WeatherDataV2 = (await weather.getWeatherById(2643743)).unwrap(); // throws if error\n * const data: WeatherDataV2 | undefined = (await weather.getWeatherByCity('Helsinki', 'fi')).ok();\n *\n * const result: Result<WeatherDataV2> = await weather.getWeatherByLatLon(60.1699, 24.9384);\n * result.match({\n * Ok: (data: WeatherDataV2) => console.log(data),\n * Err: (err: DOMException | TypeError) => console.error(err),\n * });\n *\n * if(result.isOk) {\n * const data: WeatherDataV2 = data.ok();\n * } else {\n * const err: DOMException | TypeError = data.err();\n * }\n */\nexport class OpenWeatherV2 {\n\tprivate cache: ICacheOrAsync<WeatherDataV2> | undefined;\n\tprivate loadableApiKey: Loadable<string>;\n\tprivate apiHandler: IOpenWeatherV2;\n\t/**\n\t * OpenWeatherV2 constructor\n\t * @param {Loadable<string>} loadableApiKey - Loadable API key\n\t * @param {ICacheOrAsync<WeatherDataV2>=} cache - optional async cache implementation\n\t * @param {IOpenWeatherV2=} apiHandler - optional API handler implementation for mocking\n\t */\n\tconstructor(loadableApiKey: Loadable<string>, cache?: ICacheOrAsync<WeatherDataV2>, apiHandler: IOpenWeatherV2 = defaultImplementation) {\n\t\tthis.loadableApiKey = loadableApiKey;\n\t\tthis.cache = cache;\n\t\tthis.apiHandler = apiHandler;\n\t}\n\n\t/**\n\t * get weather by Id\n\t * @param {number} id - Weather station ID\n\t * @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```\n\t * @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise\n\t * @example\n\t * const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherResultById(id: 564, {lang: 'fi'});\n\t * if (result.isOk) {\n\t * const weatherData: WeatherDataV2 = result.ok();\n\t * } else {\n\t * const error: DOMException | TypeError = result.err();\n\t * }\n\t */\n\tpublic async getWeatherById(id: number, opts: OpenWeatherV2CommonOptions = {}): Promise<Result<WeatherDataV2, DOMException | TypeError>> {\n\t\ttry {\n\t\t\tconst cacheKey = this.buildBaseCacheKey(`id:${id}`, opts);\n\t\t\tlet cacheEntry = this.cache && (await this.cache.get(cacheKey));\n\t\t\tif (!cacheEntry) {\n\t\t\t\tconst params = await this.buildBaseParams(opts);\n\t\t\t\tparams.append('id', String(id));\n\t\t\t\tcacheEntry = await this.handleFetch(cacheKey, params, opts);\n\t\t\t}\n\t\t\treturn Ok(cacheEntry);\n\t\t} catch (err) {\n\t\t\treturn Err(fetchErrorWrapper(err));\n\t\t}\n\t}\n\n\t/**\n\t * get weather with city name and optional country code\n\t * @param {string} city - City name\n\t * @param {countryCode=} countryCode - Optional Country code\n\t * @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```\n\t * @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise\n\t * @example\n\t * const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByCity('Helsinki', 'fi', {lang: 'fi'});\n\t * if (result.isOk) {\n\t * const weatherData: WeatherDataV2 = result.ok();\n\t * } else {\n\t * const error: DOMException | TypeError = result.err();\n\t * }\n\t */\n\tpublic async getWeatherByCity(\n\t\tcity: string,\n\t\tcountryCode?: CountryCode,\n\t\topts: OpenWeatherV2CommonOptions = {},\n\t): Promise<Result<WeatherDataV2, DOMException | TypeError>> {\n\t\ttry {\n\t\t\tconst cacheKey = this.buildBaseCacheKey(`q:${city}:${countryCode}`, opts);\n\t\t\tlet cacheEntry = this.cache && (await this.cache.get(cacheKey));\n\t\t\tif (!cacheEntry) {\n\t\t\t\tconst params = await this.buildBaseParams(opts);\n\t\t\t\tparams.append('q', countryCode ? `${city},${countryCode}` : city);\n\t\t\t\tcacheEntry = await this.handleFetch(cacheKey, params, opts);\n\t\t\t}\n\t\t\treturn Ok(cacheEntry);\n\t\t} catch (err) {\n\t\t\treturn Err(fetchErrorWrapper(err));\n\t\t}\n\t}\n\n\t/**\n\t * get weather with latitude and longitude with Result\n\t * @param {number} lat - Latitude\n\t * @param {number} lon - Longitude\n\t * @param {OpenWeatherV2CommonOptions=} opts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```\n\t * @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise\n\t * @example\n\t * const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByLatLon(60.1699, 24.9384, {lang: 'fi'});\n\t * if (result.isOk) {\n\t * const weatherData: WeatherDataV2 = result.ok();\n\t * } else {\n\t * const error: DOMException | TypeError = result.err();\n\t * }\n\t */\n\tpublic async getWeatherByLatLon(lat: number, lon: number, opts: OpenWeatherV2CommonOptions = {}): Promise<Result<WeatherDataV2, DOMException | TypeError>> {\n\t\ttry {\n\t\t\tconst cacheKey = this.buildBaseCacheKey(`latlon:${lat}:${lon}`, opts);\n\t\t\tlet cacheEntry = this.cache && (await this.cache.get(cacheKey));\n\t\t\tif (!cacheEntry) {\n\t\t\t\tconst params = await this.buildBaseParams(opts);\n\t\t\t\tparams.append('lat', String(lat));\n\t\t\t\tparams.append('lon', String(lon));\n\t\t\t\tcacheEntry = await this.handleFetch(cacheKey, params, opts);\n\t\t\t}\n\t\t\treturn Ok(cacheEntry);\n\t\t} catch (err) {\n\t\t\treturn Err(fetchErrorWrapper(err));\n\t\t}\n\t}\n\n\tprivate async buildBaseParams({lang, units}: OpenWeatherV2CommonOptions): Promise<URLSearchParams> {\n\t\tconst apiKey = await (typeof this.loadableApiKey === 'function' ? this.loadableApiKey() : this.loadableApiKey);\n\t\tconst params = new URLSearchParams();\n\t\tlang && params.append('lang', lang);\n\t\tunits && params.append('units', units);\n\t\tparams.append('appid', apiKey);\n\t\treturn params;\n\t}\n\n\t/**\n\t * build base cache key\n\t * @param main - main cache key prefix\n\t * @param opts - OpenWeatherV2CommonOptions\n\t * @returns {CacheKey}\n\t */\n\tprivate buildBaseCacheKey(main: string, {lang, units}: OpenWeatherV2CommonOptions): string {\n\t\treturn `${main}:${lang}:${units}`;\n\t}\n\n\tprivate async handleFetch(cacheKey: string, params: URLSearchParams, opts: OpenWeatherV2CommonOptions): Promise<WeatherDataV2> {\n\t\tconst data = await this.apiHandler.dataWeatherApi(params);\n\t\tassertWeatherDataV2(data);\n\t\tif (this.cache) {\n\t\t\tawait this.cache.set(cacheKey, data);\n\t\t\tif (!cacheKey.startsWith('id:')) {\n\t\t\t\t// update id cache too\n\t\t\t\tawait this.cache.set(this.buildBaseCacheKey(`id:${data.id}`, opts), data);\n\t\t\t}\n\t\t}\n\t\treturn data;\n\t}\n}\n"]}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./OpenWeatherV2"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./types"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./lib"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./interfaces"), exports);
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"./src/","sources":["index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,kDAAwB;AACxB,gDAAsB;AACtB,uDAA6B","sourcesContent":["export * from './OpenWeatherV2';\nexport * from './types';\nexport * from './lib';\nexport * from './interfaces';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IOpenWeatherV2.js","sourceRoot":"./src/","sources":["interfaces/IOpenWeatherV2.ts"],"names":[],"mappings":"","sourcesContent":["import {WeatherDataV2} from '../types/v2';\n\n/**\n * Interface for OpenWeatherMap API v2 implementation.\n */\nexport interface IOpenWeatherV2 {\n\tdataWeatherApi: (params: URLSearchParams) => Promise<WeatherDataV2>;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './IOpenWeatherV2';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"./src/","sources":["interfaces/index.ts"],"names":[],"mappings":";;;AAAA,2DAAiC","sourcesContent":["export * from './IOpenWeatherV2';\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchErrorWrapper = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Ensures that the error is a DOMException or TypeError.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
function fetchErrorWrapper(err) {
|
|
9
|
+
if (err instanceof DOMException || err instanceof TypeError) {
|
|
10
|
+
return err;
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
return new TypeError(`Unknown error: ${String(err)}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.fetchErrorWrapper = fetchErrorWrapper;
|
|
17
|
+
//# sourceMappingURL=fetchUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchUtils.js","sourceRoot":"./src/","sources":["lib/fetchUtils.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,GAAY;IAC7C,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,YAAY,SAAS,EAAE;QAC5D,OAAO,GAAG,CAAC;KACX;SAAM;QACN,OAAO,IAAI,SAAS,CAAC,kBAAkB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;KACtD;AACF,CAAC;AAND,8CAMC","sourcesContent":["/**\n * Ensures that the error is a DOMException or TypeError.\n * @internal\n */\nexport function fetchErrorWrapper(err: unknown): DOMException | TypeError {\n\tif (err instanceof DOMException || err instanceof TypeError) {\n\t\treturn err;\n\t} else {\n\t\treturn new TypeError(`Unknown error: ${String(err)}`);\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './fetchUtils';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"./src/","sources":["lib/index.ts"],"names":[],"mappings":";;;AAAA,uDAA6B","sourcesContent":["export * from './fetchUtils';\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const CountryCodeList: readonly ["af", "ax", "al", "dz", "as", "ad", "ao", "ai", "aq", "ag", "ar", "am", "aw", "au", "at", "az", "bs", "bh", "bd", "bb", "by", "be", "bz", "bj", "bm", "bt", "bo", "bq", "ba", "bw", "bv", "br", "io", "bn", "bg", "bf", "bi", "kh", "cm", "ca", "cv", "ky", "cf", "td", "cl", "cn", "cx", "cc", "co", "km", "cg", "cd", "ck", "cr", "ci", "hr", "cu", "cw", "cy", "cz", "dk", "dj", "dm", "do", "ec", "eg", "sv", "gq", "er", "ee", "et", "fk", "fo", "fj", "fi", "fr", "gf", "pf", "tf", "ga", "gm", "ge", "de", "gh", "gi", "gr", "gl", "gd", "gp", "gu", "gt", "gg", "gn", "gw", "gy", "ht", "hm", "va", "hn", "hk", "hu", "is", "in", "id", "ir", "iq", "ie", "im", "il", "it", "jm", "jp", "je", "jo", "kz", "ke", "ki", "kp", "kr", "kw", "kg", "la", "lv", "lb", "ls", "lr", "ly", "li", "lt", "lu", "mo", "mk", "mg", "mw", "my", "mv", "ml", "mt", "mh", "mq", "mr", "mu", "yt", "mx", "fm", "md", "mc", "mn", "me", "ms", "ma", "mz", "mm", "na", "nr", "np", "nl", "nc", "nz", "ni", "ne", "ng", "nu", "nf", "mp", "no", "om", "pk", "pw", "ps", "pa", "pg", "py", "pe", "ph", "pn", "pl", "pt", "pr", "qa", "re", "ro", "ru", "rw", "bl", "sh", "kn", "lc", "mf", "pm", "vc", "ws", "sm", "st", "sa", "sn", "rs", "sc", "sl", "sg", "sx", "sk", "si", "sb", "so", "za", "gs", "ss", "es", "lk", "sd", "sr", "sj", "sz", "se", "ch", "sy", "tw", "tj", "tz", "th", "tl", "tg", "tk", "to", "tt", "tn", "tr", "tm", "tc", "tv", "ug", "ua", "ae", "gb", "us", "um", "uy", "uz", "vu", "ve", "vn", "vg", "vi", "wf", "eh", "ye", "zm", "zw"];
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare const CountryCodeSchema: z.ZodEnum<["af", "ax", "al", "dz", "as", "ad", "ao", "ai", "aq", "ag", "ar", "am", "aw", "au", "at", "az", "bs", "bh", "bd", "bb", "by", "be", "bz", "bj", "bm", "bt", "bo", "bq", "ba", "bw", "bv", "br", "io", "bn", "bg", "bf", "bi", "kh", "cm", "ca", "cv", "ky", "cf", "td", "cl", "cn", "cx", "cc", "co", "km", "cg", "cd", "ck", "cr", "ci", "hr", "cu", "cw", "cy", "cz", "dk", "dj", "dm", "do", "ec", "eg", "sv", "gq", "er", "ee", "et", "fk", "fo", "fj", "fi", "fr", "gf", "pf", "tf", "ga", "gm", "ge", "de", "gh", "gi", "gr", "gl", "gd", "gp", "gu", "gt", "gg", "gn", "gw", "gy", "ht", "hm", "va", "hn", "hk", "hu", "is", "in", "id", "ir", "iq", "ie", "im", "il", "it", "jm", "jp", "je", "jo", "kz", "ke", "ki", "kp", "kr", "kw", "kg", "la", "lv", "lb", "ls", "lr", "ly", "li", "lt", "lu", "mo", "mk", "mg", "mw", "my", "mv", "ml", "mt", "mh", "mq", "mr", "mu", "yt", "mx", "fm", "md", "mc", "mn", "me", "ms", "ma", "mz", "mm", "na", "nr", "np", "nl", "nc", "nz", "ni", "ne", "ng", "nu", "nf", "mp", "no", "om", "pk", "pw", "ps", "pa", "pg", "py", "pe", "ph", "pn", "pl", "pt", "pr", "qa", "re", "ro", "ru", "rw", "bl", "sh", "kn", "lc", "mf", "pm", "vc", "ws", "sm", "st", "sa", "sn", "rs", "sc", "sl", "sg", "sx", "sk", "si", "sb", "so", "za", "gs", "ss", "es", "lk", "sd", "sr", "sj", "sz", "se", "ch", "sy", "tw", "tj", "tz", "th", "tl", "tg", "tk", "to", "tt", "tn", "tr", "tm", "tc", "tv", "ug", "ua", "ae", "gb", "us", "um", "uy", "uz", "vu", "ve", "vn", "vg", "vi", "wf", "eh", "ye", "zm", "zw"]>;
|
|
7
|
+
export type CountryCode = z.infer<typeof CountryCodeSchema>;
|