weather-i18n 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/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # weather-i18n
2
+
3
+ A lightweight, fully typed TypeScript library for internationalizing, validating, and mapping weather condition codes (WMO 4677) with multilingual descriptions and popular icon sets.
4
+
5
+ ## Features
6
+
7
+ - 🌐 **Internationalization (i18n)**: Translate WMO 4677 weather codes into multiple languages (`en`, `es`) with day/night phase support (`day` / `night`) and fallback language support.
8
+ - 📐 **Complete Specification**: Comprehensive definitions, human-readable keys (`key`), and reverse mappings for WMO 4677 weather codes.
9
+ - 🛡️ **Zod Validation**: Flexible schema to validate and transform numeric inputs (`95`), string values (`"95"`), or human-readable keys (`"thunderstorm_slight_moderate_no_hail"`).
10
+ - 🎨 **Icon Mapping**: Automatically map weather codes to popular icon packs such as OpenMeteo and Pixelarticons, with both day and night variants.
11
+ - 📦 **Tree-Shaking & Subpath Imports**: Import only what you need or access the raw JSON data directly.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ # Using pnpm
17
+ pnpm add weather-i18n
18
+
19
+ # Using npm
20
+ npm install weather-i18n
21
+
22
+ # Using yarn
23
+ yarn add weather-i18n
24
+ ```
25
+
26
+ ## Import Options
27
+
28
+ Once the package is installed, you can import it in different ways depending on your bundling strategy and project architecture.
29
+
30
+ ### 1. Main Import (Full Bundle)
31
+
32
+ ```ts
33
+ import { WMO4677 } from "weather-i18n";
34
+
35
+ // Unified access to spec, i18n, validator, and icons
36
+ const desc = WMO4677.i18n("es")(95, "day");
37
+ const parsed = WMO4677.validator.parse("95");
38
+ ```
39
+
40
+ ### 2. WMO 4677 Module
41
+
42
+ ```ts
43
+ import WMO4677 from "weather-i18n/wmo_4677";
44
+
45
+ const desc = WMO4677.i18n("en")(3, "night");
46
+ ```
47
+
48
+ ### 3. Subpath Imports
49
+
50
+ To optimize your bundle size or use specific features independently:
51
+
52
+ ```ts
53
+ // Internationalization
54
+ import WMO4677I18n from "weather-i18n/wmo_4677/i18n";
55
+ const getDesc = WMO4677I18n("es", "en");
56
+ console.log(getDesc(95, "day")); // "Thunderstorm"
57
+
58
+ // Complete specification
59
+ import WMO4677Spec from "weather-i18n/wmo_4677/spec";
60
+ console.log(WMO4677Spec[95].key); // "thunderstorm_slight_moderate_no_hail"
61
+
62
+ // Zod validator
63
+ import WMO4677Validator from "weather-i18n/wmo_4677/validator";
64
+ const result = WMO4677Validator.parse("05");
65
+
66
+ // Icons (All)
67
+ import WMO4677Icons from "weather-i18n/wmo_4677/icons";
68
+ console.log(WMO4677Icons.openmeteo(95, "day"));
69
+
70
+ // Individual icon helpers
71
+ import WMO4677Pixelarticons from "weather-i18n/wmo_4677/icons/pixelarticons";
72
+ import WMO4677OpenMeteo from "weather-i18n/wmo_4677/icons/openmeteo";
73
+
74
+ console.log(WMO4677Pixelarticons(95, "night"));
75
+ console.log(WMO4677OpenMeteo(95, "day"));
76
+ ```
77
+
78
+ ### 4. Direct JSON Imports
79
+
80
+ You can import the original JSON data files using Import Attributes (or assertions, depending on your environment):
81
+
82
+ ```ts
83
+ import WMO4677I18nEN from "weather-i18n/wmo_4677/data/i18n/en.json" with { format: "json" };
84
+ import WMO4677I18nES from "weather-i18n/wmo_4677/data/i18n/es.json" with { format: "json" };
85
+ import WMO4677OpenMeteo from "weather-i18n/wmo_4677/data/icons/openmeteo.json" with { format: "json" };
86
+ import WMO4677Pixelarticons from "weather-i18n/wmo_4677/data/icons/pixelarticons.json" with { format: "json" };
87
+ ```
88
+
89
+ *(Note: In Node.js v20+/v22+ and modern bundlers, `with { type: "json" }` is also supported.)*
90
+
91
+ ---
92
+
93
+ ## API Overview
94
+
95
+ ### Internationalization (`i18n`)
96
+
97
+ Create a formatter by specifying the desired language and, optionally, a fallback language:
98
+
99
+ ```ts
100
+ import WMO4677I18n from "weather-i18n/wmo_4677/i18n";
101
+
102
+ const getDesc = WMO4677I18n("es", "en");
103
+
104
+ // Get the daytime description for code 95
105
+ const daytimeText = getDesc(95, "day"); // "Tormenta"
106
+
107
+ // Get the nighttime description
108
+ const nighttimeText = getDesc(95, "night");
109
+ ```
110
+
111
+ ### Zod Validator (`validator`)
112
+
113
+ Parses input values as integers (`0-99`), strings (`"05"`), or human-readable keys (`"haze"`), returning a structured object:
114
+
115
+ ```ts
116
+ import WMO4677Validator from "weather-i18n/wmo_4677/validator";
117
+
118
+ const data = WMO4677Validator.parse("5");
119
+ // Result:
120
+ // {
121
+ // code: 5,
122
+ // key: "haze",
123
+ // description: "Haze"
124
+ // }
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Development & Scripts
130
+
131
+ If you'd like to contribute or run the local build and validation scripts:
132
+
133
+ ```bash
134
+ # Install dependencies
135
+ pnpm install
136
+
137
+ # Compile TypeScript into /dist
138
+ pnpm build
139
+
140
+ # Run tests and validation
141
+ pnpm test
142
+ ```
143
+
144
+ ## License
145
+
146
+ [ISC](LICENSE)
@@ -0,0 +1,4 @@
1
+ import WMO4677 from "./wmo_4677";
2
+ export { WMO4677 };
3
+ export default WMO4677;
4
+ export * from "./wmo_4677";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import WMO4677 from "./wmo_4677";
2
+ export { WMO4677 };
3
+ export default WMO4677;
4
+ export * from "./wmo_4677";
@@ -0,0 +1,114 @@
1
+ {
2
+ "0": {
3
+ "day": "Sunny",
4
+ "night": "Clear"
5
+ },
6
+ "1": {
7
+ "day": "Mainly Sunny",
8
+ "night": "Mainly Clear"
9
+ },
10
+ "2": {
11
+ "day": "Partly Cloudy",
12
+ "night": "Partly Cloudy"
13
+ },
14
+ "3": {
15
+ "day": "Cloudy",
16
+ "night": "Cloudy"
17
+ },
18
+ "45": {
19
+ "day": "Foggy",
20
+ "night": "Foggy"
21
+ },
22
+ "48": {
23
+ "day": "Rime Fog",
24
+ "night": "Rime Fog"
25
+ },
26
+ "51": {
27
+ "day": "Light Drizzle",
28
+ "night": "Light Drizzle"
29
+ },
30
+ "53": {
31
+ "day": "Drizzle",
32
+ "night": "Drizzle"
33
+ },
34
+ "55": {
35
+ "day": "Heavy Drizzle",
36
+ "night": "Heavy Drizzle"
37
+ },
38
+ "56": {
39
+ "day": "Light Freezing Drizzle",
40
+ "night": "Light Freezing Drizzle"
41
+ },
42
+ "57": {
43
+ "day": "Freezing Drizzle",
44
+ "night": "Freezing Drizzle"
45
+ },
46
+ "61": {
47
+ "day": "Light Rain",
48
+ "night": "Light Rain"
49
+ },
50
+ "63": {
51
+ "day": "Rain",
52
+ "night": "Rain"
53
+ },
54
+ "65": {
55
+ "day": "Heavy Rain",
56
+ "night": "Heavy Rain"
57
+ },
58
+ "66": {
59
+ "day": "Light Freezing Rain",
60
+ "night": "Light Freezing Rain"
61
+ },
62
+ "67": {
63
+ "day": "Freezing Rain",
64
+ "night": "Freezing Rain"
65
+ },
66
+ "71": {
67
+ "day": "Light Snow",
68
+ "night": "Light Snow"
69
+ },
70
+ "73": {
71
+ "day": "Snow",
72
+ "night": "Snow"
73
+ },
74
+ "75": {
75
+ "day": "Heavy Snow",
76
+ "night": "Heavy Snow"
77
+ },
78
+ "77": {
79
+ "day": "Snow Grains",
80
+ "night": "Snow Grains"
81
+ },
82
+ "80": {
83
+ "day": "Light Showers",
84
+ "night": "Light Showers"
85
+ },
86
+ "81": {
87
+ "day": "Showers",
88
+ "night": "Showers"
89
+ },
90
+ "82": {
91
+ "day": "Heavy Showers",
92
+ "night": "Heavy Showers"
93
+ },
94
+ "85": {
95
+ "day": "Light Snow Showers",
96
+ "night": "Light Snow Showers"
97
+ },
98
+ "86": {
99
+ "day": "Snow Showers",
100
+ "night": "Snow Showers"
101
+ },
102
+ "95": {
103
+ "day": "Thunderstorm",
104
+ "night": "Thunderstorm"
105
+ },
106
+ "96": {
107
+ "day": "Light Thunderstorms With Hail",
108
+ "night": "Light Thunderstorms With Hail"
109
+ },
110
+ "99": {
111
+ "day": "Thunderstorm With Hail",
112
+ "night": "Thunderstorm With Hail"
113
+ }
114
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "0": {
3
+ "day": "Soleado",
4
+ "night": "Despejado"
5
+ },
6
+ "1": {
7
+ "day": "Mayormente soleado",
8
+ "night": "Mayormente despejado"
9
+ },
10
+ "2": {
11
+ "day": "Parcialmente nublado",
12
+ "night": "Parcialmente nublado"
13
+ },
14
+ "3": {
15
+ "day": "Nublado",
16
+ "night": "Nublado"
17
+ },
18
+ "45": {
19
+ "day": "Con niebla",
20
+ "night": "Con niebla"
21
+ },
22
+ "48": {
23
+ "day": "Niebla con cencellada",
24
+ "night": "Niebla con cencellada"
25
+ },
26
+ "51": {
27
+ "day": "Llovizna débil",
28
+ "night": "Llovizna débil"
29
+ },
30
+ "53": {
31
+ "day": "Llovizna",
32
+ "night": "Llovizna"
33
+ },
34
+ "55": {
35
+ "day": "Llovizna intensa",
36
+ "night": "Llovizna intensa"
37
+ },
38
+ "56": {
39
+ "day": "Llovizna helada débil",
40
+ "night": "Llovizna helada débil"
41
+ },
42
+ "57": {
43
+ "day": "Llovizna helada",
44
+ "night": "Llovizna helada"
45
+ },
46
+ "61": {
47
+ "day": "Lluvia débil",
48
+ "night": "Lluvia débil"
49
+ },
50
+ "63": {
51
+ "day": "Lluvia",
52
+ "night": "Lluvia"
53
+ },
54
+ "65": {
55
+ "day": "Lluvia intensa",
56
+ "night": "Lluvia intensa"
57
+ },
58
+ "66": {
59
+ "day": "Lluvia helada débil",
60
+ "night": "Lluvia helada débil"
61
+ },
62
+ "67": {
63
+ "day": "Lluvia helada",
64
+ "night": "Lluvia helada"
65
+ },
66
+ "71": {
67
+ "day": "Nieve débil",
68
+ "night": "Nieve débil"
69
+ },
70
+ "73": {
71
+ "day": "Nieve",
72
+ "night": "Nieve"
73
+ },
74
+ "75": {
75
+ "day": "Nevada intensa",
76
+ "night": "Nevada intensa"
77
+ },
78
+ "77": {
79
+ "day": "Granos de nieve",
80
+ "night": "Granos de nieve"
81
+ },
82
+ "80": {
83
+ "day": "Chubascos débiles",
84
+ "night": "Chubascos débiles"
85
+ },
86
+ "81": {
87
+ "day": "Chubascos",
88
+ "night": "Chubascos"
89
+ },
90
+ "82": {
91
+ "day": "Chubascos intensos",
92
+ "night": "Chubascos intensos"
93
+ },
94
+ "85": {
95
+ "day": "Chubascos de nieve débiles",
96
+ "night": "Chubascos de nieve débiles"
97
+ },
98
+ "86": {
99
+ "day": "Chubascos de nieve",
100
+ "night": "Chubascos de nieve"
101
+ },
102
+ "95": {
103
+ "day": "Tormenta",
104
+ "night": "Tormenta"
105
+ },
106
+ "96": {
107
+ "day": "Tormenta con granizo débil",
108
+ "night": "Tormenta con granizo débil"
109
+ },
110
+ "99": {
111
+ "day": "Tormenta con granizo",
112
+ "night": "Tormenta con granizo"
113
+ }
114
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "0": {
3
+ "day": "http://openweathermap.org/img/wn/01d@2x.png",
4
+ "night": "http://openweathermap.org/img/wn/01n@2x.png"
5
+ },
6
+ "1": {
7
+ "day": "http://openweathermap.org/img/wn/01d@2x.png",
8
+ "night": "http://openweathermap.org/img/wn/01n@2x.png"
9
+ },
10
+ "2": {
11
+ "day": "http://openweathermap.org/img/wn/02d@2x.png",
12
+ "night": "http://openweathermap.org/img/wn/02n@2x.png"
13
+ },
14
+ "3": {
15
+ "day": "http://openweathermap.org/img/wn/03d@2x.png",
16
+ "night": "http://openweathermap.org/img/wn/03n@2x.png"
17
+ },
18
+ "45": {
19
+ "day": "http://openweathermap.org/img/wn/50d@2x.png",
20
+ "night": "http://openweathermap.org/img/wn/50n@2x.png"
21
+ },
22
+ "48": {
23
+ "day": "http://openweathermap.org/img/wn/50d@2x.png",
24
+ "night": "http://openweathermap.org/img/wn/50n@2x.png"
25
+ },
26
+ "51": {
27
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
28
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
29
+ },
30
+ "53": {
31
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
32
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
33
+ },
34
+ "55": {
35
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
36
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
37
+ },
38
+ "56": {
39
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
40
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
41
+ },
42
+ "57": {
43
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
44
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
45
+ },
46
+ "61": {
47
+ "day": "http://openweathermap.org/img/wn/10d@2x.png",
48
+ "night": "http://openweathermap.org/img/wn/10n@2x.png"
49
+ },
50
+ "63": {
51
+ "day": "http://openweathermap.org/img/wn/10d@2x.png",
52
+ "night": "http://openweathermap.org/img/wn/10n@2x.png"
53
+ },
54
+ "65": {
55
+ "day": "http://openweathermap.org/img/wn/10d@2x.png",
56
+ "night": "http://openweathermap.org/img/wn/10n@2x.png"
57
+ },
58
+ "66": {
59
+ "day": "http://openweathermap.org/img/wn/10d@2x.png",
60
+ "night": "http://openweathermap.org/img/wn/10n@2x.png"
61
+ },
62
+ "67": {
63
+ "day": "http://openweathermap.org/img/wn/10d@2x.png",
64
+ "night": "http://openweathermap.org/img/wn/10n@2x.png"
65
+ },
66
+ "71": {
67
+ "day": "http://openweathermap.org/img/wn/13d@2x.png",
68
+ "night": "http://openweathermap.org/img/wn/13n@2x.png"
69
+ },
70
+ "73": {
71
+ "day": "http://openweathermap.org/img/wn/13d@2x.png",
72
+ "night": "http://openweathermap.org/img/wn/13n@2x.png"
73
+ },
74
+ "75": {
75
+ "day": "http://openweathermap.org/img/wn/13d@2x.png",
76
+ "night": "http://openweathermap.org/img/wn/13n@2x.png"
77
+ },
78
+ "77": {
79
+ "day": "http://openweathermap.org/img/wn/13d@2x.png",
80
+ "night": "http://openweathermap.org/img/wn/13n@2x.png"
81
+ },
82
+ "80": {
83
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
84
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
85
+ },
86
+ "81": {
87
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
88
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
89
+ },
90
+ "82": {
91
+ "day": "http://openweathermap.org/img/wn/09d@2x.png",
92
+ "night": "http://openweathermap.org/img/wn/09n@2x.png"
93
+ },
94
+ "85": {
95
+ "day": "http://openweathermap.org/img/wn/13d@2x.png",
96
+ "night": "http://openweathermap.org/img/wn/13n@2x.png"
97
+ },
98
+ "86": {
99
+ "day": "http://openweathermap.org/img/wn/13d@2x.png",
100
+ "night": "http://openweathermap.org/img/wn/13n@2x.png"
101
+ },
102
+ "95": {
103
+ "day": "http://openweathermap.org/img/wn/11d@2x.png",
104
+ "night": "http://openweathermap.org/img/wn/11n@2x.png"
105
+ },
106
+ "96": {
107
+ "day": "http://openweathermap.org/img/wn/11d@2x.png",
108
+ "night": "http://openweathermap.org/img/wn/11n@2x.png"
109
+ },
110
+ "99": {
111
+ "day": "http://openweathermap.org/img/wn/11d@2x.png",
112
+ "night": "http://openweathermap.org/img/wn/11n@2x.png"
113
+ }
114
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "0": {
3
+ "day": "Sun",
4
+ "night": "Moon"
5
+ },
6
+ "1": {
7
+ "day": "CloudSun",
8
+ "night": "CloudMoon"
9
+ },
10
+ "2": {
11
+ "day": "CloudSun",
12
+ "night": "CloudMoon"
13
+ },
14
+ "3": {
15
+ "day": "Cloud",
16
+ "night": "Cloud"
17
+ },
18
+ "45": {
19
+ "day": "Waves",
20
+ "night": "Waves"
21
+ },
22
+ "48": {
23
+ "day": "Waves",
24
+ "night": "Waves"
25
+ },
26
+ "51": {
27
+ "day": "Rain",
28
+ "night": "Rain"
29
+ },
30
+ "53": {
31
+ "day": "Rain",
32
+ "night": "Rain"
33
+ },
34
+ "55": {
35
+ "day": "Rain2",
36
+ "night": "Rain2"
37
+ },
38
+ "56": {
39
+ "day": "Rain2",
40
+ "night": "Rain2"
41
+ },
42
+ "57": {
43
+ "day": "Rain2",
44
+ "night": "Rain2"
45
+ },
46
+ "61": {
47
+ "day": "Rain",
48
+ "night": "Rain"
49
+ },
50
+ "63": {
51
+ "day": "Rain2",
52
+ "night": "Rain2"
53
+ },
54
+ "65": {
55
+ "day": "CloudThunderRain",
56
+ "night": "CloudThunderRain"
57
+ },
58
+ "66": {
59
+ "day": "Rain2",
60
+ "night": "Rain2"
61
+ },
62
+ "67": {
63
+ "day": "Rain2",
64
+ "night": "Rain2"
65
+ },
66
+ "71": {
67
+ "day": "Rain2",
68
+ "night": "Rain2"
69
+ },
70
+ "73": {
71
+ "day": "CloudSnow",
72
+ "night": "CloudSnow"
73
+ },
74
+ "75": {
75
+ "day": "CloudSnow2",
76
+ "night": "CloudSnow2"
77
+ },
78
+ "77": {
79
+ "day": "Rain2",
80
+ "night": "Rain2"
81
+ },
82
+ "80": {
83
+ "day": "Rain",
84
+ "night": "Rain"
85
+ },
86
+ "81": {
87
+ "day": "Rain2",
88
+ "night": "Rain2"
89
+ },
90
+ "82": {
91
+ "day": "CloudThunderRain",
92
+ "night": "CloudThunderRain"
93
+ },
94
+ "85": {
95
+ "day": "Rain2",
96
+ "night": "Rain2"
97
+ },
98
+ "86": {
99
+ "day": "CloudSnow2",
100
+ "night": "CloudSnow2"
101
+ },
102
+ "95": {
103
+ "day": "CloudThunder",
104
+ "night": "CloudThunder"
105
+ },
106
+ "96": {
107
+ "day": "CloudThunderRain",
108
+ "night": "CloudThunderRain"
109
+ },
110
+ "99": {
111
+ "day": "CloudThunder",
112
+ "night": "CloudThunder"
113
+ }
114
+ }
@@ -0,0 +1,2 @@
1
+ import type { DayPhase, Language, WMO4677Code } from "./types";
2
+ export default function WMO4677I18n(language: Language, fallbackLanguage?: Language): (code: WMO4677Code, dayPhase?: DayPhase) => string | undefined;
@@ -0,0 +1,13 @@
1
+ import { default as wmoEnDescription } from "./data/i18n/en.json" with { type: "json" };
2
+ import { default as wmoEsDescription } from "./data/i18n/es.json" with { type: "json" };
3
+ const DESCRIPTIONS_BY_LANGUAGE = {
4
+ en: wmoEnDescription,
5
+ es: wmoEsDescription,
6
+ };
7
+ export default function WMO4677I18n(language, fallbackLanguage = "en") {
8
+ return function getDescription(code, dayPhase = "day") {
9
+ return DESCRIPTIONS_BY_LANGUAGE[language][code]?.[dayPhase] ??
10
+ DESCRIPTIONS_BY_LANGUAGE[fallbackLanguage][code]?.[dayPhase] ??
11
+ undefined;
12
+ };
13
+ }
@@ -0,0 +1,7 @@
1
+ import openmeteo from "./openmeteo";
2
+ import pixelarticons from "./pixelarticons";
3
+ declare const _default: {
4
+ openmeteo: typeof openmeteo;
5
+ pixelarticons: typeof pixelarticons;
6
+ };
7
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import openmeteo from "./openmeteo";
2
+ import pixelarticons from "./pixelarticons";
3
+ export default {
4
+ openmeteo,
5
+ pixelarticons,
6
+ };
@@ -0,0 +1,2 @@
1
+ import type { DayPhase, WMO4677Code } from "../types";
2
+ export default function WMO4677OpenMeteoIcon(code: WMO4677Code, dayPhase?: DayPhase): string | undefined;
@@ -0,0 +1,6 @@
1
+ import { default as wmoOpenMeteoIcons } from "../data/icons/openmeteo.json" with {
2
+ type: "json"
3
+ };
4
+ export default function WMO4677OpenMeteoIcon(code, dayPhase = "day") {
5
+ return wmoOpenMeteoIcons[code]?.[dayPhase];
6
+ }
@@ -0,0 +1,2 @@
1
+ import type { DayPhase, WMO4677Code } from "../types";
2
+ export default function WMO4677PixelarticonsIcon(code: WMO4677Code, dayPhase?: DayPhase): string | undefined;
@@ -0,0 +1,6 @@
1
+ import { default as wmoPixelarticonsIcons } from "../data/icons/pixelarticons.json" with {
2
+ type: "json"
3
+ };
4
+ export default function WMO4677PixelarticonsIcon(code, dayPhase = "day") {
5
+ return wmoPixelarticonsIcons[code]?.[dayPhase];
6
+ }