@mharj/openweathermap 0.0.2 → 0.0.4

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.
@@ -4,15 +4,46 @@ exports.OpenWeatherV2 = void 0;
4
4
  const types_1 = require("./types");
5
5
  const mharj_result_1 = require("mharj-result");
6
6
  const fetchUtils_1 = require("./lib/fetchUtils");
7
+ const fetchResult = (0, mharj_result_1.safeAsyncResultBuilder)(fetch);
8
+ function isJson(response) {
9
+ const contentType = response.headers.get('content-type');
10
+ return (contentType && contentType.startsWith('application/json')) || false;
11
+ }
12
+ function isOpenWeatherError(data) {
13
+ return typeof data === 'object' && data !== null && 'cod' in data && 'message' in data;
14
+ }
15
+ const basePath = 'https://api.openweathermap.org/data/2.5/weather';
16
+ function buildUrl(params) {
17
+ return `${basePath}?${params.toString()}`;
18
+ }
19
+ function buildLogUrl(params) {
20
+ const logParams = new URLSearchParams(params);
21
+ logParams.set('appid', '***');
22
+ return buildUrl(logParams);
23
+ }
7
24
  const defaultImplementation = {
8
25
  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);
26
+ const logUrl = buildLogUrl(params);
27
+ const result = await fetchResult(buildUrl(params));
28
+ if (!result.isOk) {
29
+ return (0, mharj_result_1.Err)(result.err());
12
30
  }
13
- const data = (await resp.json());
31
+ const res = result.ok();
32
+ if (!res.ok) {
33
+ if (isJson(res)) {
34
+ const data = res.json();
35
+ if (isOpenWeatherError(data)) {
36
+ return (0, mharj_result_1.Err)(new TypeError(`OpenWeatherV2 error: ${data.message} from ${logUrl}`));
37
+ }
38
+ }
39
+ return (0, mharj_result_1.Err)(new TypeError(`OpenWeatherV2 http error: ${res.status} ${res.statusText} from ${logUrl}`));
40
+ }
41
+ if (!isJson(res)) {
42
+ return (0, mharj_result_1.Err)(new TypeError(`OpenWeatherV2 response is not json payload from ${logUrl}`));
43
+ }
44
+ const data = await (0, mharj_result_1.safeAsyncResult)(res.json());
14
45
  (0, types_1.assertWeatherDataV2)(data);
15
- return data;
46
+ return (0, mharj_result_1.Ok)(data);
16
47
  },
17
48
  };
18
49
  /**
@@ -158,7 +189,8 @@ class OpenWeatherV2 {
158
189
  return `${main}:${lang}:${units}`;
159
190
  }
160
191
  async handleFetch(cacheKey, params, opts) {
161
- const data = await this.apiHandler.dataWeatherApi(params);
192
+ const dataApiResult = await this.apiHandler.dataWeatherApi(params);
193
+ const data = dataApiResult.unwrap();
162
194
  (0, types_1.assertWeatherDataV2)(data);
163
195
  if (this.cache) {
164
196
  await this.cache.set(cacheKey, data);
@@ -1 +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"]}
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, safeAsyncResult, safeAsyncResultBuilder} from 'mharj-result';\nimport {fetchErrorWrapper} from './lib/fetchUtils';\nimport type {ICacheOrAsync} from '@avanio/expire-cache';\nimport type {IOpenWeatherV2} from './interfaces/IOpenWeatherV2';\n\nconst fetchResult = safeAsyncResultBuilder<Parameters<typeof fetch>, Response, SyntaxError | TypeError>(fetch);\n\nfunction isJson(response: Response): boolean {\n\tconst contentType = response.headers.get('content-type');\n\treturn (contentType && contentType.startsWith('application/json')) || false;\n}\n\nfunction isOpenWeatherError(data: unknown): data is {cod: string; message: string} {\n\treturn typeof data === 'object' && data !== null && 'cod' in data && 'message' in data;\n}\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 basePath = 'https://api.openweathermap.org/data/2.5/weather';\n\nfunction buildUrl(params: URLSearchParams): string {\n\treturn `${basePath}?${params.toString()}`;\n}\n\nfunction buildLogUrl(params: URLSearchParams): string {\n\tconst logParams = new URLSearchParams(params);\n\tlogParams.set('appid', '***');\n\treturn buildUrl(logParams);\n}\n\nconst defaultImplementation: IOpenWeatherV2 = {\n\tdataWeatherApi: async (params: URLSearchParams): Promise<Result<WeatherDataV2, SyntaxError | TypeError>> => {\n\t\tconst logUrl = buildLogUrl(params);\n\t\tconst result = await fetchResult(buildUrl(params));\n\t\tif (!result.isOk) {\n\t\t\treturn Err(result.err());\n\t\t}\n\t\tconst res = result.ok();\n\t\tif (!res.ok) {\n\t\t\tif (isJson(res)) {\n\t\t\t\tconst data = res.json();\n\t\t\t\tif (isOpenWeatherError(data)) {\n\t\t\t\t\treturn Err(new TypeError(`OpenWeatherV2 error: ${data.message} from ${logUrl}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Err(new TypeError(`OpenWeatherV2 http error: ${res.status} ${res.statusText} from ${logUrl}`));\n\t\t}\n\t\tif (!isJson(res)) {\n\t\t\treturn Err(new TypeError(`OpenWeatherV2 response is not json payload from ${logUrl}`));\n\t\t}\n\t\tconst data = await safeAsyncResult<unknown, SyntaxError>(res.json());\n\t\tassertWeatherDataV2(data);\n\t\treturn Ok<WeatherDataV2, SyntaxError | TypeError>(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 dataApiResult = await this.apiHandler.dataWeatherApi(params);\n\t\tconst data: WeatherDataV2 = dataApiResult.unwrap();\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"]}
@@ -1,7 +1,8 @@
1
+ import { Result } from 'mharj-result';
1
2
  import { WeatherDataV2 } from '../types/v2';
2
3
  /**
3
4
  * Interface for OpenWeatherMap API v2 implementation.
4
5
  */
5
6
  export interface IOpenWeatherV2 {
6
- dataWeatherApi: (params: URLSearchParams) => Promise<WeatherDataV2>;
7
+ dataWeatherApi: (params: URLSearchParams) => Promise<Result<WeatherDataV2, SyntaxError | TypeError>>;
7
8
  }
@@ -1 +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"]}
1
+ {"version":3,"file":"IOpenWeatherV2.js","sourceRoot":"./src/","sources":["interfaces/IOpenWeatherV2.ts"],"names":[],"mappings":"","sourcesContent":["import {Result} from 'mharj-result';\nimport {WeatherDataV2} from '../types/v2';\n\n/**\n * Interface for OpenWeatherMap API v2 implementation.\n */\nexport interface IOpenWeatherV2 {\n\tdataWeatherApi: (params: URLSearchParams) => Promise<Result<WeatherDataV2, SyntaxError | TypeError>>;\n}\n"]}
@@ -54,24 +54,24 @@ export declare const weatherDataV2Schema: z.ZodObject<{
54
54
  }>;
55
55
  name: z.ZodString;
56
56
  rain: z.ZodOptional<z.ZodObject<{
57
- '1h': z.ZodNumber;
58
- '3h': z.ZodNumber;
57
+ '1h': z.ZodOptional<z.ZodNumber>;
58
+ '3h': z.ZodOptional<z.ZodNumber>;
59
59
  }, "strip", z.ZodTypeAny, {
60
- '1h': number;
61
- '3h': number;
60
+ '1h'?: number | undefined;
61
+ '3h'?: number | undefined;
62
62
  }, {
63
- '1h': number;
64
- '3h': number;
63
+ '1h'?: number | undefined;
64
+ '3h'?: number | undefined;
65
65
  }>>;
66
66
  snow: z.ZodOptional<z.ZodObject<{
67
- '1h': z.ZodNumber;
68
- '3h': z.ZodNumber;
67
+ '1h': z.ZodOptional<z.ZodNumber>;
68
+ '3h': z.ZodOptional<z.ZodNumber>;
69
69
  }, "strip", z.ZodTypeAny, {
70
- '1h': number;
71
- '3h': number;
70
+ '1h'?: number | undefined;
71
+ '3h'?: number | undefined;
72
72
  }, {
73
- '1h': number;
74
- '3h': number;
73
+ '1h'?: number | undefined;
74
+ '3h'?: number | undefined;
75
75
  }>>;
76
76
  sys: z.ZodObject<{
77
77
  country: z.ZodString;
@@ -166,12 +166,12 @@ export declare const weatherDataV2Schema: z.ZodObject<{
166
166
  deg: number;
167
167
  };
168
168
  rain?: {
169
- '1h': number;
170
- '3h': number;
169
+ '1h'?: number | undefined;
170
+ '3h'?: number | undefined;
171
171
  } | undefined;
172
172
  snow?: {
173
- '1h': number;
174
- '3h': number;
173
+ '1h'?: number | undefined;
174
+ '3h'?: number | undefined;
175
175
  } | undefined;
176
176
  }, {
177
177
  base: string;
@@ -216,12 +216,12 @@ export declare const weatherDataV2Schema: z.ZodObject<{
216
216
  deg: number;
217
217
  };
218
218
  rain?: {
219
- '1h': number;
220
- '3h': number;
219
+ '1h'?: number | undefined;
220
+ '3h'?: number | undefined;
221
221
  } | undefined;
222
222
  snow?: {
223
- '1h': number;
224
- '3h': number;
223
+ '1h'?: number | undefined;
224
+ '3h'?: number | undefined;
225
225
  } | undefined;
226
226
  }>;
227
227
  export type WeatherDataV2 = z.infer<typeof weatherDataV2Schema>;
@@ -32,12 +32,12 @@ const windSchema = zod_1.z.object({
32
32
  deg: zod_1.z.number(),
33
33
  });
34
34
  const rainSchema = zod_1.z.object({
35
- '1h': zod_1.z.number(),
36
- '3h': zod_1.z.number(),
35
+ '1h': zod_1.z.number().optional(),
36
+ '3h': zod_1.z.number().optional(),
37
37
  });
38
38
  const snowSchema = zod_1.z.object({
39
- '1h': zod_1.z.number(),
40
- '3h': zod_1.z.number(),
39
+ '1h': zod_1.z.number().optional(),
40
+ '3h': zod_1.z.number().optional(),
41
41
  });
42
42
  const sysSchema = zod_1.z.object({
43
43
  country: zod_1.z.string(),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"./src/","sources":["types/v2/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {iconSchema} from './Icon';\nimport {weatherIdSchema} from './weatherIdGroup';\nimport {z} from 'zod';\nexport * from './Icon';\nexport * from './Language';\nexport * from './weatherIdGroup';\n\nconst coordSchema = z.object({\n\tlon: z.number(),\n\tlat: z.number(),\n});\n\nconst weatherSchema = z.object({\n\tdescription: z.string(),\n\ticon: iconSchema,\n\tid: weatherIdSchema,\n\tmain: z.string(),\n});\n\nconst mainSchema = z.object({\n\tgrnd_level: z.number().optional(),\n\thumidity: z.number(),\n\tpressure: z.number(),\n\tsea_level: z.number().optional(),\n\ttemp: z.number(),\n\ttemp_max: z.number(),\n\ttemp_min: z.number(),\n});\n\nconst windSchema = z.object({\n\tspeed: z.number(),\n\tdeg: z.number(),\n});\n\nconst rainSchema = z.object({\n\t'1h': z.number(),\n\t'3h': z.number(),\n});\n\nconst snowSchema = z.object({\n\t'1h': z.number(),\n\t'3h': z.number(),\n});\n\nconst sysSchema = z.object({\n\tcountry: z.string(),\n\tid: z.number(),\n\tmessage: z.number().optional(),\n\tsunrise: z.number(),\n\tsunset: z.number(),\n\ttype: z.number(),\n});\n\n/**\n * @internal\n */\nexport const weatherDataV2Schema = z.object({\n\tbase: z.string(),\n\tclouds: z.object({\n\t\tall: z.number(),\n\t}),\n\tcod: z.number(),\n\tcoord: coordSchema,\n\tdt: z.number(),\n\tid: z.number(),\n\tmain: mainSchema,\n\tname: z.string(),\n\train: rainSchema.optional(),\n\tsnow: snowSchema.optional(),\n\tsys: sysSchema,\n\ttimezone: z.number(),\n\tvisibility: z.number(),\n\tweather: z.array(weatherSchema),\n\twind: windSchema,\n});\n\nexport type WeatherDataV2 = z.infer<typeof weatherDataV2Schema>;\n\nexport function isWeatherDataV2(data: unknown): data is WeatherDataV2 {\n\treturn weatherDataV2Schema.safeParse(data).success;\n}\n\nexport function assertWeatherDataV2(data: unknown): asserts data is WeatherDataV2 {\n\tweatherDataV2Schema.parse(data);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"./src/","sources":["types/v2/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {iconSchema} from './Icon';\nimport {weatherIdSchema} from './weatherIdGroup';\nimport {z} from 'zod';\nexport * from './Icon';\nexport * from './Language';\nexport * from './weatherIdGroup';\n\nconst coordSchema = z.object({\n\tlon: z.number(),\n\tlat: z.number(),\n});\n\nconst weatherSchema = z.object({\n\tdescription: z.string(),\n\ticon: iconSchema,\n\tid: weatherIdSchema,\n\tmain: z.string(),\n});\n\nconst mainSchema = z.object({\n\tgrnd_level: z.number().optional(),\n\thumidity: z.number(),\n\tpressure: z.number(),\n\tsea_level: z.number().optional(),\n\ttemp: z.number(),\n\ttemp_max: z.number(),\n\ttemp_min: z.number(),\n});\n\nconst windSchema = z.object({\n\tspeed: z.number(),\n\tdeg: z.number(),\n});\n\nconst rainSchema = z.object({\n\t'1h': z.number().optional(),\n\t'3h': z.number().optional(),\n});\n\nconst snowSchema = z.object({\n\t'1h': z.number().optional(),\n\t'3h': z.number().optional(),\n});\n\nconst sysSchema = z.object({\n\tcountry: z.string(),\n\tid: z.number(),\n\tmessage: z.number().optional(),\n\tsunrise: z.number(),\n\tsunset: z.number(),\n\ttype: z.number(),\n});\n\n/**\n * @internal\n */\nexport const weatherDataV2Schema = z.object({\n\tbase: z.string(),\n\tclouds: z.object({\n\t\tall: z.number(),\n\t}),\n\tcod: z.number(),\n\tcoord: coordSchema,\n\tdt: z.number(),\n\tid: z.number(),\n\tmain: mainSchema,\n\tname: z.string(),\n\train: rainSchema.optional(),\n\tsnow: snowSchema.optional(),\n\tsys: sysSchema,\n\ttimezone: z.number(),\n\tvisibility: z.number(),\n\tweather: z.array(weatherSchema),\n\twind: windSchema,\n});\n\nexport type WeatherDataV2 = z.infer<typeof weatherDataV2Schema>;\n\nexport function isWeatherDataV2(data: unknown): data is WeatherDataV2 {\n\treturn weatherDataV2Schema.safeParse(data).success;\n}\n\nexport function assertWeatherDataV2(data: unknown): asserts data is WeatherDataV2 {\n\tweatherDataV2Schema.parse(data);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mharj/openweathermap",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Open Weather API Client",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -59,28 +59,27 @@
59
59
  },
60
60
  "homepage": "https://github.com/mharj/ts-openweather#readme",
61
61
  "dependencies": {
62
- "@avanio/expire-cache": "^0.2.0",
63
- "mharj-result": "^0.4.5",
64
- "tslib": "^2.6.0",
62
+ "@avanio/expire-cache": "^0.3.2",
63
+ "mharj-result": "^0.5.1",
64
+ "tslib": "^2.6.1",
65
65
  "zod": "^3.21.4"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/chai": "^4.3.5",
69
69
  "@types/mocha": "^10.0.1",
70
- "@types/node": "^18.17.0",
71
- "@typescript-eslint/eslint-plugin": "^6.1.0",
72
- "@typescript-eslint/parser": "^6.1.0",
70
+ "@types/node": "^18.17.2",
71
+ "@typescript-eslint/eslint-plugin": "^6.2.1",
72
+ "@typescript-eslint/parser": "^6.2.1",
73
73
  "chai": "^4.3.7",
74
- "dotenv": "^16.3.1",
75
- "eslint": "^8.45.0",
76
- "eslint-config-prettier": "^8.8.0",
74
+ "eslint": "^8.46.0",
75
+ "eslint-config-prettier": "^8.10.0",
77
76
  "eslint-config-standard": "^17.1.0",
78
- "eslint-plugin-deprecation": "^1.4.1",
77
+ "eslint-plugin-deprecation": "^1.5.0",
79
78
  "eslint-plugin-prettier": "^5.0.0",
80
79
  "eslint-plugin-sonarjs": "^0.19.0",
81
80
  "mocha": "^10.2.0",
82
81
  "nyc": "^15.1.0",
83
- "prettier": "^3.0.0",
82
+ "prettier": "^3.0.1",
84
83
  "source-map-support": "^0.5.21",
85
84
  "ts-node": "^10.9.1",
86
85
  "typedoc": "^0.24.8",