@mharj/openweathermap 0.1.0 → 0.1.2

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/dist/index.cjs ADDED
@@ -0,0 +1,967 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let _luolapeikko_result_option = require("@luolapeikko/result-option");
3
+ let zod = require("zod");
4
+
5
+ //#region src/lib/fetchUtils.ts
6
+ /**
7
+ * Ensures that the error is a DOMException or TypeError.
8
+ * @internal
9
+ */
10
+ function fetchErrorWrapper(err) {
11
+ if (err instanceof DOMException || err instanceof TypeError) return err;
12
+ else return /* @__PURE__ */ new TypeError(`Unknown error: ${String(err)}`);
13
+ }
14
+
15
+ //#endregion
16
+ //#region src/types/v2/Icon.ts
17
+ /**
18
+ * @internal
19
+ */
20
+ const dayIconListSchema = zod.z.enum([
21
+ "01d",
22
+ "02d",
23
+ "03d",
24
+ "04d",
25
+ "09d",
26
+ "10d",
27
+ "11d",
28
+ "13d",
29
+ "50d"
30
+ ]);
31
+ /**
32
+ * @internal
33
+ */
34
+ const nightIconListSchema = zod.z.enum([
35
+ "01n",
36
+ "02n",
37
+ "03n",
38
+ "04n",
39
+ "09n",
40
+ "10n",
41
+ "11n",
42
+ "13n",
43
+ "50n"
44
+ ]);
45
+ /**
46
+ * @internal
47
+ */
48
+ const iconSchema = zod.z.union([dayIconListSchema, nightIconListSchema]);
49
+
50
+ //#endregion
51
+ //#region src/types/v2/weatherIdGroup.ts
52
+ /**
53
+ * This is a list of weather ids, groups and descriptions from OpenWeatherMap API
54
+ */
55
+ const weatherIdGroup = [
56
+ {
57
+ id: 200,
58
+ group: "thunderstorm",
59
+ description: "thunderstorm_with_light_rain"
60
+ },
61
+ {
62
+ id: 201,
63
+ group: "thunderstorm",
64
+ description: "thunderstorm_with_rain"
65
+ },
66
+ {
67
+ id: 202,
68
+ group: "thunderstorm",
69
+ description: "thunderstorm_with_heavy_rain"
70
+ },
71
+ {
72
+ id: 210,
73
+ group: "thunderstorm",
74
+ description: "light_thunderstorm"
75
+ },
76
+ {
77
+ id: 211,
78
+ group: "thunderstorm",
79
+ description: "thunderstorm"
80
+ },
81
+ {
82
+ id: 212,
83
+ group: "thunderstorm",
84
+ description: "heavy_thunderstorm"
85
+ },
86
+ {
87
+ id: 221,
88
+ group: "thunderstorm",
89
+ description: "ragged_thunderstorm"
90
+ },
91
+ {
92
+ id: 230,
93
+ group: "thunderstorm",
94
+ description: "thunderstorm_with_light_drizzle"
95
+ },
96
+ {
97
+ id: 231,
98
+ group: "thunderstorm",
99
+ description: "thunderstorm_with_drizzle"
100
+ },
101
+ {
102
+ id: 232,
103
+ group: "thunderstorm",
104
+ description: "thunderstorm_with_heavy_drizzle"
105
+ },
106
+ {
107
+ id: 300,
108
+ group: "drizzle",
109
+ description: "light_intensity_drizzle"
110
+ },
111
+ {
112
+ id: 301,
113
+ group: "drizzle",
114
+ description: "drizzle"
115
+ },
116
+ {
117
+ id: 302,
118
+ group: "drizzle",
119
+ description: "heavy_intensity_drizzle"
120
+ },
121
+ {
122
+ id: 310,
123
+ group: "drizzle",
124
+ description: "light_intensity_drizzle_rain"
125
+ },
126
+ {
127
+ id: 311,
128
+ group: "drizzle",
129
+ description: "drizzle_rain"
130
+ },
131
+ {
132
+ id: 312,
133
+ group: "drizzle",
134
+ description: "heavy_intensity_drizzle_rain"
135
+ },
136
+ {
137
+ id: 313,
138
+ group: "drizzle",
139
+ description: "shower_rain_and_drizzle"
140
+ },
141
+ {
142
+ id: 314,
143
+ group: "drizzle",
144
+ description: "heavy_shower_rain_and_drizzle"
145
+ },
146
+ {
147
+ id: 321,
148
+ group: "drizzle",
149
+ description: "shower_drizzle"
150
+ },
151
+ {
152
+ id: 500,
153
+ group: "rain",
154
+ description: "light_rain"
155
+ },
156
+ {
157
+ id: 501,
158
+ group: "rain",
159
+ description: "moderate_rain"
160
+ },
161
+ {
162
+ id: 502,
163
+ group: "rain",
164
+ description: "heavy_intensity_rain"
165
+ },
166
+ {
167
+ id: 503,
168
+ group: "rain",
169
+ description: "very_heavy_rain"
170
+ },
171
+ {
172
+ id: 504,
173
+ group: "rain",
174
+ description: "extreme_rain"
175
+ },
176
+ {
177
+ id: 511,
178
+ group: "rain",
179
+ description: "freezing_rain"
180
+ },
181
+ {
182
+ id: 520,
183
+ group: "rain",
184
+ description: "light_intensity_shower_rain"
185
+ },
186
+ {
187
+ id: 521,
188
+ group: "rain",
189
+ description: "shower_rain"
190
+ },
191
+ {
192
+ id: 522,
193
+ group: "rain",
194
+ description: "heavy_intensity_shower_rain"
195
+ },
196
+ {
197
+ id: 531,
198
+ group: "rain",
199
+ description: "ragged_shower_rain"
200
+ },
201
+ {
202
+ id: 600,
203
+ group: "snow",
204
+ description: "light_snow"
205
+ },
206
+ {
207
+ id: 601,
208
+ group: "snow",
209
+ description: "snow"
210
+ },
211
+ {
212
+ id: 602,
213
+ group: "snow",
214
+ description: "heavy_snow"
215
+ },
216
+ {
217
+ id: 611,
218
+ group: "snow",
219
+ description: "sleet"
220
+ },
221
+ {
222
+ id: 612,
223
+ group: "snow",
224
+ description: "light_shower_sleet"
225
+ },
226
+ {
227
+ id: 613,
228
+ group: "snow",
229
+ description: "shower_sleet"
230
+ },
231
+ {
232
+ id: 615,
233
+ group: "snow",
234
+ description: "light_rain_and_snow"
235
+ },
236
+ {
237
+ id: 616,
238
+ group: "snow",
239
+ description: "rain_and_snow"
240
+ },
241
+ {
242
+ id: 620,
243
+ group: "snow",
244
+ description: "light_shower_snow"
245
+ },
246
+ {
247
+ id: 621,
248
+ group: "snow",
249
+ description: "shower_snow"
250
+ },
251
+ {
252
+ id: 622,
253
+ group: "snow",
254
+ description: "heavy_shower_snow"
255
+ },
256
+ {
257
+ id: 701,
258
+ group: "atmosphere",
259
+ description: "mist"
260
+ },
261
+ {
262
+ id: 711,
263
+ group: "atmosphere",
264
+ description: "smoke"
265
+ },
266
+ {
267
+ id: 721,
268
+ group: "atmosphere",
269
+ description: "haze"
270
+ },
271
+ {
272
+ id: 731,
273
+ group: "atmosphere",
274
+ description: "sand_dust_whirls"
275
+ },
276
+ {
277
+ id: 741,
278
+ group: "atmosphere",
279
+ description: "fog"
280
+ },
281
+ {
282
+ id: 751,
283
+ group: "atmosphere",
284
+ description: "sand"
285
+ },
286
+ {
287
+ id: 761,
288
+ group: "atmosphere",
289
+ description: "dust"
290
+ },
291
+ {
292
+ id: 762,
293
+ group: "atmosphere",
294
+ description: "volcanic_ash"
295
+ },
296
+ {
297
+ id: 771,
298
+ group: "atmosphere",
299
+ description: "squalls"
300
+ },
301
+ {
302
+ id: 781,
303
+ group: "atmosphere",
304
+ description: "tornado"
305
+ },
306
+ {
307
+ id: 800,
308
+ group: "clear",
309
+ description: "clear_sky"
310
+ },
311
+ {
312
+ id: 801,
313
+ group: "clouds",
314
+ description: "few_clouds_11-25_percent"
315
+ },
316
+ {
317
+ id: 802,
318
+ group: "clouds",
319
+ description: "scattered_clouds_25-50_percent"
320
+ },
321
+ {
322
+ id: 803,
323
+ group: "clouds",
324
+ description: "broken_clouds_51-84_percent"
325
+ },
326
+ {
327
+ id: 804,
328
+ group: "clouds",
329
+ description: "overcast_clouds_85-100_percent"
330
+ }
331
+ ];
332
+ /**
333
+ * Weather id schema
334
+ * @internal
335
+ */
336
+ const weatherIdSchema = zod.z.custom((val) => {
337
+ if (typeof val !== "number") return {
338
+ message: "Expected a number",
339
+ success: false
340
+ };
341
+ if (!weatherIdGroup.find((x) => x.id === val)) return {
342
+ message: "Expected a valid weather id",
343
+ success: false
344
+ };
345
+ return val;
346
+ });
347
+ /**
348
+ * get weather description key from weather id
349
+ * @param id - weather id
350
+ * @returns {Option<WeatherDescription>} option for weather description key
351
+ * @example
352
+ * const weatherComponent = ({data}) => {
353
+ * const key = getWeatherV2Description(data.weather[0]?.id).unwrapOr('unknown');
354
+ * return (
355
+ * <div>
356
+ * {t(`weather:${key}`}
357
+ * </div>
358
+ * );
359
+ * }
360
+ */
361
+ function getWeatherV2Description(id) {
362
+ return _luolapeikko_result_option.Option.fromNullish(weatherIdGroup.find((x) => x.id === id)?.description);
363
+ }
364
+
365
+ //#endregion
366
+ //#region src/types/v2/Language.ts
367
+ const langCodes = [
368
+ "af",
369
+ "al",
370
+ "ar",
371
+ "az",
372
+ "bg",
373
+ "ca",
374
+ "cz",
375
+ "da",
376
+ "de",
377
+ "el",
378
+ "en",
379
+ "eu",
380
+ "fa",
381
+ "fi",
382
+ "fr",
383
+ "gl",
384
+ "he",
385
+ "hi",
386
+ "hr",
387
+ "hu",
388
+ "id",
389
+ "it",
390
+ "ja",
391
+ "kr",
392
+ "la",
393
+ "lt",
394
+ "mk",
395
+ "no",
396
+ "nl",
397
+ "pl",
398
+ "pt",
399
+ "pt",
400
+ "ro",
401
+ "ru",
402
+ "sv",
403
+ "sk",
404
+ "sl",
405
+ "sp",
406
+ "sr",
407
+ "th",
408
+ "tr",
409
+ "ua",
410
+ "vi",
411
+ "zh_cn",
412
+ "zh_tw",
413
+ "zu"
414
+ ];
415
+ const langCodeSchema = zod.z.enum(langCodes);
416
+
417
+ //#endregion
418
+ //#region src/types/v2/index.ts
419
+ const coordSchema = zod.z.object({
420
+ lon: zod.z.number(),
421
+ lat: zod.z.number()
422
+ });
423
+ const weatherSchema = zod.z.object({
424
+ description: zod.z.string(),
425
+ icon: iconSchema,
426
+ id: weatherIdSchema,
427
+ main: zod.z.string()
428
+ });
429
+ const mainSchema = zod.z.object({
430
+ grnd_level: zod.z.number().optional(),
431
+ humidity: zod.z.number(),
432
+ pressure: zod.z.number(),
433
+ sea_level: zod.z.number().optional(),
434
+ temp: zod.z.number(),
435
+ temp_max: zod.z.number(),
436
+ temp_min: zod.z.number()
437
+ });
438
+ const windSchema = zod.z.object({
439
+ speed: zod.z.number(),
440
+ deg: zod.z.number()
441
+ });
442
+ const rainSchema = zod.z.object({
443
+ "1h": zod.z.number().optional(),
444
+ "3h": zod.z.number().optional()
445
+ });
446
+ const snowSchema = zod.z.object({
447
+ "1h": zod.z.number().optional(),
448
+ "3h": zod.z.number().optional()
449
+ });
450
+ const sysSchema = zod.z.object({
451
+ country: zod.z.string(),
452
+ id: zod.z.number().optional(),
453
+ message: zod.z.number().optional(),
454
+ sunrise: zod.z.number(),
455
+ sunset: zod.z.number(),
456
+ type: zod.z.number().optional()
457
+ });
458
+ /**
459
+ * @internal
460
+ */
461
+ const weatherDataV2Schema = zod.z.object({
462
+ base: zod.z.string(),
463
+ clouds: zod.z.object({ all: zod.z.number() }),
464
+ cod: zod.z.number(),
465
+ coord: coordSchema,
466
+ dt: zod.z.number(),
467
+ id: zod.z.number(),
468
+ main: mainSchema,
469
+ name: zod.z.string(),
470
+ rain: rainSchema.optional(),
471
+ snow: snowSchema.optional(),
472
+ sys: sysSchema,
473
+ timezone: zod.z.number(),
474
+ visibility: zod.z.number(),
475
+ weather: zod.z.array(weatherSchema),
476
+ wind: windSchema
477
+ });
478
+ function isWeatherDataV2(data) {
479
+ return weatherDataV2Schema.safeParse(data).success;
480
+ }
481
+ function assertWeatherDataV2(data) {
482
+ weatherDataV2Schema.parse(data);
483
+ }
484
+
485
+ //#endregion
486
+ //#region src/types/ISO3166-Countries.ts
487
+ const CountryCodeList = [
488
+ "af",
489
+ "ax",
490
+ "al",
491
+ "dz",
492
+ "as",
493
+ "ad",
494
+ "ao",
495
+ "ai",
496
+ "aq",
497
+ "ag",
498
+ "ar",
499
+ "am",
500
+ "aw",
501
+ "au",
502
+ "at",
503
+ "az",
504
+ "bs",
505
+ "bh",
506
+ "bd",
507
+ "bb",
508
+ "by",
509
+ "be",
510
+ "bz",
511
+ "bj",
512
+ "bm",
513
+ "bt",
514
+ "bo",
515
+ "bq",
516
+ "ba",
517
+ "bw",
518
+ "bv",
519
+ "br",
520
+ "io",
521
+ "bn",
522
+ "bg",
523
+ "bf",
524
+ "bi",
525
+ "kh",
526
+ "cm",
527
+ "ca",
528
+ "cv",
529
+ "ky",
530
+ "cf",
531
+ "td",
532
+ "cl",
533
+ "cn",
534
+ "cx",
535
+ "cc",
536
+ "co",
537
+ "km",
538
+ "cg",
539
+ "cd",
540
+ "ck",
541
+ "cr",
542
+ "ci",
543
+ "hr",
544
+ "cu",
545
+ "cw",
546
+ "cy",
547
+ "cz",
548
+ "dk",
549
+ "dj",
550
+ "dm",
551
+ "do",
552
+ "ec",
553
+ "eg",
554
+ "sv",
555
+ "gq",
556
+ "er",
557
+ "ee",
558
+ "et",
559
+ "fk",
560
+ "fo",
561
+ "fj",
562
+ "fi",
563
+ "fr",
564
+ "gf",
565
+ "pf",
566
+ "tf",
567
+ "ga",
568
+ "gm",
569
+ "ge",
570
+ "de",
571
+ "gh",
572
+ "gi",
573
+ "gr",
574
+ "gl",
575
+ "gd",
576
+ "gp",
577
+ "gu",
578
+ "gt",
579
+ "gg",
580
+ "gn",
581
+ "gw",
582
+ "gy",
583
+ "ht",
584
+ "hm",
585
+ "va",
586
+ "hn",
587
+ "hk",
588
+ "hu",
589
+ "is",
590
+ "in",
591
+ "id",
592
+ "ir",
593
+ "iq",
594
+ "ie",
595
+ "im",
596
+ "il",
597
+ "it",
598
+ "jm",
599
+ "jp",
600
+ "je",
601
+ "jo",
602
+ "kz",
603
+ "ke",
604
+ "ki",
605
+ "kp",
606
+ "kr",
607
+ "kw",
608
+ "kg",
609
+ "la",
610
+ "lv",
611
+ "lb",
612
+ "ls",
613
+ "lr",
614
+ "ly",
615
+ "li",
616
+ "lt",
617
+ "lu",
618
+ "mo",
619
+ "mk",
620
+ "mg",
621
+ "mw",
622
+ "my",
623
+ "mv",
624
+ "ml",
625
+ "mt",
626
+ "mh",
627
+ "mq",
628
+ "mr",
629
+ "mu",
630
+ "yt",
631
+ "mx",
632
+ "fm",
633
+ "md",
634
+ "mc",
635
+ "mn",
636
+ "me",
637
+ "ms",
638
+ "ma",
639
+ "mz",
640
+ "mm",
641
+ "na",
642
+ "nr",
643
+ "np",
644
+ "nl",
645
+ "nc",
646
+ "nz",
647
+ "ni",
648
+ "ne",
649
+ "ng",
650
+ "nu",
651
+ "nf",
652
+ "mp",
653
+ "no",
654
+ "om",
655
+ "pk",
656
+ "pw",
657
+ "ps",
658
+ "pa",
659
+ "pg",
660
+ "py",
661
+ "pe",
662
+ "ph",
663
+ "pn",
664
+ "pl",
665
+ "pt",
666
+ "pr",
667
+ "qa",
668
+ "re",
669
+ "ro",
670
+ "ru",
671
+ "rw",
672
+ "bl",
673
+ "sh",
674
+ "kn",
675
+ "lc",
676
+ "mf",
677
+ "pm",
678
+ "vc",
679
+ "ws",
680
+ "sm",
681
+ "st",
682
+ "sa",
683
+ "sn",
684
+ "rs",
685
+ "sc",
686
+ "sl",
687
+ "sg",
688
+ "sx",
689
+ "sk",
690
+ "si",
691
+ "sb",
692
+ "so",
693
+ "za",
694
+ "gs",
695
+ "ss",
696
+ "es",
697
+ "lk",
698
+ "sd",
699
+ "sr",
700
+ "sj",
701
+ "sz",
702
+ "se",
703
+ "ch",
704
+ "sy",
705
+ "tw",
706
+ "tj",
707
+ "tz",
708
+ "th",
709
+ "tl",
710
+ "tg",
711
+ "tk",
712
+ "to",
713
+ "tt",
714
+ "tn",
715
+ "tr",
716
+ "tm",
717
+ "tc",
718
+ "tv",
719
+ "ug",
720
+ "ua",
721
+ "ae",
722
+ "gb",
723
+ "us",
724
+ "um",
725
+ "uy",
726
+ "uz",
727
+ "vu",
728
+ "ve",
729
+ "vn",
730
+ "vg",
731
+ "vi",
732
+ "wf",
733
+ "eh",
734
+ "ye",
735
+ "zm",
736
+ "zw"
737
+ ];
738
+ /**
739
+ * @internal
740
+ */
741
+ const CountryCodeSchema = zod.z.enum(CountryCodeList);
742
+
743
+ //#endregion
744
+ //#region src/OpenWeatherV2.ts
745
+ const fetchResult = _luolapeikko_result_option.Result.wrapAsyncFn(fetch);
746
+ function toParams(data) {
747
+ return Object.entries(data).reduce((acc, [key, value]) => {
748
+ acc[key] = String(value);
749
+ return acc;
750
+ }, {});
751
+ }
752
+ function isJson(response) {
753
+ return response.headers.get("content-type")?.startsWith("application/json") ?? false;
754
+ }
755
+ function isOpenWeatherError(data) {
756
+ return typeof data === "object" && data !== null && "cod" in data && "message" in data;
757
+ }
758
+ const defaultCommonOptions = {
759
+ lang: "en",
760
+ units: "standard"
761
+ };
762
+ function buildOpts(opts) {
763
+ return Object.assign({}, defaultCommonOptions, opts);
764
+ }
765
+ const basePath = "https://api.openweathermap.org/data/2.5/weather";
766
+ function buildUrl(params) {
767
+ return `${basePath}?${params.toString()}`;
768
+ }
769
+ function buildLogUrl(params) {
770
+ const logParams = new URLSearchParams(params);
771
+ logParams.set("appid", "***");
772
+ return buildUrl(logParams);
773
+ }
774
+ const defaultImplementation = { dataWeatherApi: async (params) => {
775
+ const logUrl = buildLogUrl(params);
776
+ const result = await fetchResult(buildUrl(params));
777
+ if (!result.isOk) return (0, _luolapeikko_result_option.Err)(result.err());
778
+ const res = result.ok();
779
+ if (!res.ok) {
780
+ if (isJson(res)) {
781
+ const data = await res.json();
782
+ if (isOpenWeatherError(data)) return (0, _luolapeikko_result_option.Err)(/* @__PURE__ */ new TypeError(`OpenWeatherV2 error: ${data.message} from ${logUrl}`));
783
+ }
784
+ return (0, _luolapeikko_result_option.Err)(/* @__PURE__ */ new TypeError(`OpenWeatherV2 http error: ${res.status} ${res.statusText} from ${logUrl}`));
785
+ }
786
+ if (!isJson(res)) return (0, _luolapeikko_result_option.Err)(/* @__PURE__ */ new TypeError(`OpenWeatherV2 response is not json payload from ${logUrl}`));
787
+ const jsonResult = await _luolapeikko_result_option.Result.safeAsyncCall(() => res.json());
788
+ if (!jsonResult.isOk) return (0, _luolapeikko_result_option.Err)(jsonResult.err());
789
+ const data = jsonResult.ok();
790
+ assertWeatherDataV2(data);
791
+ return (0, _luolapeikko_result_option.Ok)(data);
792
+ } };
793
+ /**
794
+ * Open Weather V2 API
795
+ * @example
796
+ * const weather = new OpenWeatherV2('your-api-key');
797
+ *
798
+ * const cache = new ExpireCache<WeatherDataV2>(undefined, undefined, 900000); // data 15 minutes in cache
799
+ * const weather = new OpenWeatherV2(() => Promise.resolve('your-api-key'), cache);
800
+ *
801
+ * const data: WeatherDataV2 = (await weather.getWeatherById(2643743)).unwrap(); // throws if error
802
+ * const data: WeatherDataV2 | undefined = (await weather.getWeatherByCity('Helsinki', 'fi')).ok();
803
+ *
804
+ * const result: Result<WeatherDataV2> = await weather.getWeatherByLatLon(60.1699, 24.9384);
805
+ * result.match({
806
+ * Ok: (data: WeatherDataV2) => console.log(data),
807
+ * Err: (err: DOMException | TypeError) => console.error(err),
808
+ * });
809
+ *
810
+ * if(result.isOk) {
811
+ * const data: WeatherDataV2 = data.ok();
812
+ * } else {
813
+ * const err: DOMException | TypeError = data.err();
814
+ * }
815
+ * @since v0.0.1
816
+ */
817
+ var OpenWeatherV2 = class {
818
+ cache;
819
+ loadableApiKey;
820
+ apiHandler;
821
+ fetchPromiseMap = /* @__PURE__ */ new Map();
822
+ /**
823
+ * OpenWeatherV2 constructor
824
+ * @param {Loadable<string>} loadableApiKey - Loadable API key
825
+ * @param {ICacheOrAsync<WeatherDataV2>=} cache - optional async cache implementation
826
+ * @param {IOpenWeatherV2=} apiHandler - optional API handler implementation for mocking
827
+ */
828
+ constructor(loadableApiKey, cache, apiHandler = defaultImplementation) {
829
+ this.loadableApiKey = loadableApiKey;
830
+ this.cache = cache;
831
+ this.apiHandler = apiHandler;
832
+ }
833
+ /**
834
+ * get weather by Id
835
+ * @param {number} id - Weather station ID
836
+ * @param {OpenWeatherV2CommonOptions=} currentOpts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
837
+ * @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
838
+ * @example
839
+ * const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherResultById(id: 564, {lang: 'fi'});
840
+ * if (result.isOk) {
841
+ * const weatherData: WeatherDataV2 = result.ok();
842
+ * } else {
843
+ * const error: DOMException | TypeError = result.err();
844
+ * }
845
+ */
846
+ async getWeatherById(id, currentOpts = {}) {
847
+ try {
848
+ const opts = buildOpts(currentOpts);
849
+ const cacheKey = this.buildBaseCacheKey(`id:${id}`, opts);
850
+ let cacheEntry = this.cache && await this.cache.get(cacheKey);
851
+ if (!cacheEntry) {
852
+ const params = await this.buildBaseParams(opts);
853
+ params.append("id", String(id));
854
+ cacheEntry = await this.handleFetch(cacheKey, params, opts);
855
+ }
856
+ return (0, _luolapeikko_result_option.Ok)(cacheEntry);
857
+ } catch (err) {
858
+ return (0, _luolapeikko_result_option.Err)(fetchErrorWrapper(err));
859
+ }
860
+ }
861
+ /**
862
+ * get weather with city name and optional country code
863
+ * @param {string} city - City name
864
+ * @param {countryCode=} countryCode - Optional Country code
865
+ * @param {OpenWeatherV2CommonOptions=} currentOpts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
866
+ * @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
867
+ * @example
868
+ * const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByCity('Helsinki', 'fi', {lang: 'fi'});
869
+ * if (result.isOk) {
870
+ * const weatherData: WeatherDataV2 = result.ok();
871
+ * } else {
872
+ * const error: DOMException | TypeError = result.err();
873
+ * }
874
+ */
875
+ async getWeatherByCity(city, countryCode, currentOpts = {}) {
876
+ try {
877
+ const opts = buildOpts(currentOpts);
878
+ const cacheKey = this.buildBaseCacheKey(`q:${city}:${countryCode}`, opts);
879
+ let cacheEntry = this.cache && await this.cache.get(cacheKey);
880
+ if (!cacheEntry) {
881
+ const params = await this.buildBaseParams(opts);
882
+ params.append("q", countryCode ? `${city},${countryCode}` : city);
883
+ cacheEntry = await this.handleFetch(cacheKey, params, opts);
884
+ }
885
+ return (0, _luolapeikko_result_option.Ok)(cacheEntry);
886
+ } catch (err) {
887
+ return (0, _luolapeikko_result_option.Err)(fetchErrorWrapper(err));
888
+ }
889
+ }
890
+ /**
891
+ * get weather with latitude and longitude with Result
892
+ * @param {number} lat - Latitude
893
+ * @param {number} lon - Longitude
894
+ * @param {OpenWeatherV2CommonOptions=} currentOpts - Common options, example ```{lang: 'fi', units: 'metric'}```, defaults ```{lang: 'en', units: 'standard'}```
895
+ * @return {Promise<Result<WeatherDataV2, DOMException | TypeError>>} Weather data Result Promise
896
+ * @example
897
+ * const result: Result<WeatherDataV2, DOMException | TypeError> = await weather.getWeatherByLatLon(60.1699, 24.9384, {lang: 'fi'});
898
+ * if (result.isOk) {
899
+ * const weatherData: WeatherDataV2 = result.ok();
900
+ * } else {
901
+ * const error: DOMException | TypeError = result.err();
902
+ * }
903
+ */
904
+ async getWeatherByLatLon(lat, lon, currentOpts = {}) {
905
+ try {
906
+ const opts = buildOpts(currentOpts);
907
+ const cacheKey = this.buildBaseCacheKey(`latlon:${lat}:${lon}`, opts);
908
+ let cacheEntry = this.cache && await this.cache.get(cacheKey);
909
+ if (!cacheEntry) {
910
+ const params = await this.buildBaseParams(opts);
911
+ params.append("lat", String(lat));
912
+ params.append("lon", String(lon));
913
+ cacheEntry = await this.handleFetch(cacheKey, params, opts);
914
+ }
915
+ return (0, _luolapeikko_result_option.Ok)(cacheEntry);
916
+ } catch (err) {
917
+ return (0, _luolapeikko_result_option.Err)(fetchErrorWrapper(err));
918
+ }
919
+ }
920
+ async buildBaseParams(options) {
921
+ const apiKey = await (typeof this.loadableApiKey === "function" ? this.loadableApiKey() : this.loadableApiKey);
922
+ const params = new URLSearchParams(toParams(options));
923
+ params.append("appid", apiKey);
924
+ return params;
925
+ }
926
+ /**
927
+ * build base cache key
928
+ * @param main - main cache key prefix
929
+ * @param opts - OpenWeatherV2CommonOptions
930
+ * @returns {string} cache key
931
+ */
932
+ buildBaseCacheKey(main, { lang, units }) {
933
+ return `${main}:${lang}:${units}`;
934
+ }
935
+ async handleFetch(cacheKey, params, opts) {
936
+ let promiseResult = this.fetchPromiseMap.get(cacheKey);
937
+ if (!promiseResult) {
938
+ promiseResult = this.apiHandler.dataWeatherApi(params);
939
+ this.fetchPromiseMap.set(cacheKey, promiseResult);
940
+ await promiseResult;
941
+ this.fetchPromiseMap.delete(cacheKey);
942
+ }
943
+ const data = (await promiseResult).unwrap();
944
+ assertWeatherDataV2(data);
945
+ if (this.cache) {
946
+ await this.cache.set(cacheKey, data);
947
+ if (!cacheKey.startsWith("id:")) await this.cache.set(this.buildBaseCacheKey(`id:${data.id}`, opts), data);
948
+ }
949
+ return data;
950
+ }
951
+ };
952
+
953
+ //#endregion
954
+ exports.CountryCodeList = CountryCodeList;
955
+ exports.CountryCodeSchema = CountryCodeSchema;
956
+ exports.OpenWeatherV2 = OpenWeatherV2;
957
+ exports.assertWeatherDataV2 = assertWeatherDataV2;
958
+ exports.fetchErrorWrapper = fetchErrorWrapper;
959
+ exports.getWeatherV2Description = getWeatherV2Description;
960
+ exports.iconSchema = iconSchema;
961
+ exports.isWeatherDataV2 = isWeatherDataV2;
962
+ exports.langCodeSchema = langCodeSchema;
963
+ exports.langCodes = langCodes;
964
+ exports.weatherDataV2Schema = weatherDataV2Schema;
965
+ exports.weatherIdGroup = weatherIdGroup;
966
+ exports.weatherIdSchema = weatherIdSchema;
967
+ //# sourceMappingURL=index.cjs.map