es-regional-holidays 0.1.2 → 0.2.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.es.md ADDED
@@ -0,0 +1,156 @@
1
+ # es-regional-holidays
2
+
3
+ es-regional-holidays es una librería ligera, TypeScript-first, que proporciona los festivos oficiales en España por año y comunidad autónoma, con soporte opcional para festivos locales (municipales).
4
+
5
+ Es agnóstica al framework y funciona con React, Angular, Vue y Node.js puro.
6
+
7
+ ## Características
8
+
9
+ - Festivos nacionales, autonómicos y locales (municipales)
10
+ - Un único dataset normalizado por año
11
+ - Datos opcionales a nivel de provincia y municipio
12
+ - Totalmente tipada con TypeScript
13
+ - Compatible con bundlers modernos (ESM y CJS)
14
+ - Cero dependencias en tiempo de ejecución
15
+
16
+ ## Instalación
17
+
18
+ El paquete está disponible en npm.
19
+
20
+ Usando npm:
21
+ npm install es-regional-holidays
22
+
23
+ Usando yarn:
24
+ yarn add es-regional-holidays
25
+
26
+ Usando pnpm:
27
+ pnpm add es-regional-holidays
28
+
29
+ ## Uso
30
+
31
+ ### Obtener todos los festivos de una comunidad
32
+
33
+ Devuelve los festivos **nacionales + autonómicos + locales** para una comunidad y un año.
34
+
35
+ ```ts
36
+ import { getAllHolidaysByRegionCode } from "es-regional-holidays";
37
+
38
+ const holidays = getAllHolidaysByRegionCode("CN", 2026);
39
+ ```
40
+
41
+ Ejemplo de resultado:
42
+
43
+ ```ts
44
+ [
45
+ { date: "2026-01-01", name: "Año Nuevo", scope: "national" },
46
+ { date: "2026-01-06", name: "Epifanía del Señor", scope: "regional", region: "CN" },
47
+ { date: "2026-05-30", name: "Día de Canarias", scope: "regional", region: "CN" }
48
+ ]
49
+ ```
50
+
51
+ ### Solo festivos nacionales
52
+
53
+ ```ts
54
+ import { getNationalHolidays } from "es-regional-holidays";
55
+
56
+ const national = getNationalHolidays(2026);
57
+ ```
58
+
59
+ ### Solo festivos autonómicos
60
+
61
+ ```ts
62
+ import { getRegionalHolidaysByRegionCode } from "es-regional-holidays";
63
+
64
+ const regional = getRegionalHolidaysByRegionCode("MD", 2026);
65
+ ```
66
+
67
+ ### Festivos locales (municipales)
68
+
69
+ ```ts
70
+ import { getLocalHolidaysByProvince } from "es-regional-holidays";
71
+
72
+ const valenciaLocal = getLocalHolidaysByProvince("VC", "Valencia", 2026);
73
+ ```
74
+
75
+ ### Comprobar si una fecha es festivo
76
+
77
+ ```ts
78
+ import { isHoliday } from "es-regional-holidays";
79
+
80
+ isHoliday("2026-01-01"); // true (nacional)
81
+ isHoliday("2026-05-30", "CN"); // true (autonómico)
82
+ isHoliday("2026-05-30", "MD"); // false
83
+ ```
84
+
85
+ Acepta tanto strings `YYYY-MM-DD` como objetos `Date`.
86
+
87
+ ### Comprobar solo festivos locales
88
+
89
+ ```ts
90
+ import { isLocalHoliday } from "es-regional-holidays";
91
+
92
+ isLocalHoliday("2026-01-22", "VC", "Valencia", "VALENCIA");
93
+ ```
94
+
95
+ ### Listar comunidades soportadas
96
+
97
+ ```ts
98
+ import { getAllRegions } from "es-regional-holidays";
99
+
100
+ const regions = getAllRegions(2026);
101
+ ```
102
+
103
+ Los códigos de comunidad siguen las abreviaturas oficiales del BOE.
104
+
105
+ ## Modelo de datos
106
+
107
+ ```ts
108
+ export interface Holiday {
109
+ date: string;
110
+ name: string;
111
+ scope: "national" | "regional" | "local";
112
+ region?: string;
113
+ regionName?: string;
114
+ province?: string;
115
+ locality?: string;
116
+ }
117
+ ```
118
+
119
+ ## Clasificación nacional vs autonómica
120
+
121
+ La clasificación de festivos sigue la práctica administrativa real, no solo el origen legal.
122
+
123
+ En el BOE, los festivos se marcan como:
124
+ - `*` -> Festivo nacional no sustituible
125
+ - `**` -> Festivo nacional sustituible por la comunidad autónoma
126
+ - `***` -> Festivo autonómico
127
+
128
+ En esta librería se exponen como:
129
+ - `*` -> Nacional
130
+ - `**` -> Autonómico
131
+ - `***` -> Autonómico
132
+
133
+ Algunos festivos son de origen nacional pero están gestionados por las comunidades autónomas. Para reflejar los calendarios reales, estos festivos se exponen como autonómicos en la API.
134
+
135
+ ## Fuente de datos
136
+
137
+ Los datos se obtienen principalmente del calendario oficial de la Seguridad Social y se contrastan con la resolución anual publicada en el BOE.
138
+ Por ejemplo, BOE-A-2025-21667 para el año 2026.
139
+
140
+ Los datos en bruto se conservan internamente para trazabilidad y reproducibilidad.
141
+
142
+ ## Años soportados
143
+
144
+ - 2026
145
+
146
+ Se añadirán más años de forma incremental.
147
+
148
+ ## Licencia
149
+
150
+ MIT License
151
+ Copyright (c) Juan Melo
152
+
153
+ ## Contribuir
154
+
155
+ Issues y pull requests son bienvenidos.
156
+ El objetivo del proyecto es mantenerse pequeño, predecible y sin dependencias.
package/README.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # es-regional-holidays
2
2
 
3
- es-regional-holidays is a lightweight, TypeScript-first library that provides official public holidays in Spain by year and autonomous community, based on data published in the Boletín Oficial del Estado (BOE).
3
+ es-regional-holidays is a lightweight, TypeScript-first library that provides official public holidays in Spain by year and autonomous community, with optional support for local (municipal) holidays.
4
4
 
5
- The library is framework-agnostic and can be used with React, Angular, Vue, or plain Node.js projects.
5
+ It is framework-agnostic and works with React, Angular, Vue, and plain Node.js.
6
6
 
7
7
  ## Features
8
8
 
9
- - Official holiday data sourced from the BOE
10
- - Clear distinction between national and regional holidays
11
- - Zero runtime dependencies
9
+ - National, regional, and local (municipal) holidays
10
+ - Single normalized dataset per year
11
+ - Optional province and locality-level data
12
12
  - Fully typed with TypeScript
13
13
  - Compatible with modern bundlers (ESM and CJS)
14
+ - Zero runtime dependencies
14
15
 
15
16
  ## Installation
16
17
 
@@ -25,11 +26,11 @@ yarn add es-regional-holidays
25
26
  Using pnpm:
26
27
  pnpm add es-regional-holidays
27
28
 
28
- ## Basic usage
29
+ ## Usage
29
30
 
30
31
  ### Get all holidays for a region
31
32
 
32
- Returns all applicable holidays for a given region and year, including national common holidays and region-managed holidays.
33
+ Returns **national + regional + local** holidays for a region and year.
33
34
 
34
35
  ```ts
35
36
  import { getAllHolidaysByRegionCode } from "es-regional-holidays";
@@ -47,53 +48,71 @@ Example result:
47
48
  ]
48
49
  ```
49
50
 
50
- ## Check if a date is a holiday
51
+ ### National holidays only
51
52
 
52
53
  ```ts
53
- import { isHoliday } from "es-regional-holidays";
54
+ import { getNationalHolidays } from "es-regional-holidays";
55
+
56
+ const national = getNationalHolidays(2026);
57
+ ```
58
+
59
+ ### Regional holidays only
60
+
61
+ ```ts
62
+ import { getRegionalHolidaysByRegionCode } from "es-regional-holidays";
54
63
 
55
- isHoliday("2026-05-30", "CN");
56
- isHoliday("2026-05-30", "MD");
64
+ const regional = getRegionalHolidaysByRegionCode("MD", 2026);
57
65
  ```
58
66
 
59
- The function accepts both YYYY-MM-DD strings and Date objects.
67
+ ### Local (municipal) holidays
68
+
69
+ ```ts
70
+ import { getLocalHolidaysByProvince } from "es-regional-holidays";
71
+
72
+ const valenciaLocal = getLocalHolidaysByProvince("VC", "Valencia", 2026);
73
+ ```
60
74
 
61
- ## National holidays only
75
+ ### Check if a date is a holiday
62
76
 
63
77
  ```ts
64
- import { getNationalHolidays } from "es-regional-holidays";
78
+ import { isHoliday } from "es-regional-holidays";
65
79
 
66
- const nationalHolidays = getNationalHolidays(2026);
80
+ isHoliday("2026-01-01"); // true (national)
81
+ isHoliday("2026-05-30", "CN"); // true (regional)
82
+ isHoliday("2026-05-30", "MD"); // false
67
83
  ```
68
84
 
69
- ## Regional holidays only
85
+ Accepts both `YYYY-MM-DD` strings and `Date` objects.
86
+
87
+ ### Check local holidays only
70
88
 
71
89
  ```ts
72
- import { getRegionalHolidaysByRegionCode } from "es-regional-holidays";
90
+ import { isLocalHoliday } from "es-regional-holidays";
73
91
 
74
- const regionalHolidays = getRegionalHolidaysByRegionCode("MD", 2026);
92
+ isLocalHoliday("2026-01-22", "VC", "Valencia", "VALENCIA");
75
93
  ```
76
94
 
77
- ## List supported regions
95
+ ### List supported regions
78
96
 
79
97
  ```ts
80
- import { getRegions } from "es-regional-holidays";
98
+ import { getAllRegions } from "es-regional-holidays";
81
99
 
82
- const regions = getRegions();
100
+ const regions = getAllRegions(2026);
83
101
  ```
84
102
 
85
- Region codes follow the official BOE abbreviations.
103
+ Region codes follow official BOE abbreviations.
86
104
 
87
- ## Holiday data model
105
+ ## Data model
88
106
 
89
107
  ```ts
90
108
  export interface Holiday {
91
109
  date: string;
92
110
  name: string;
111
+ scope: "national" | "regional" | "local";
93
112
  region?: string;
94
113
  regionName?: string;
95
- scope: "national" | "regional";
96
- source?: string;
114
+ province?: string;
115
+ locality?: string;
97
116
  }
98
117
  ```
99
118
 
package/dist/index.d.mts CHANGED
@@ -1,43 +1,61 @@
1
1
  type RegionCode = "AN" | "AR" | "AS" | "CB" | "CE" | "CL" | "CM" | "CN" | "CT" | "EX" | "GA" | "IB" | "MC" | "MD" | "ML" | "NC" | "PV" | "RI" | "VC";
2
- type HolidayScope = "national" | "regional";
2
+ type HolidayScope = "national" | "regional" | "local";
3
+ /** Entry as stored in the source dataset */
4
+ interface HolidayEntry {
5
+ date: string;
6
+ name: string;
7
+ }
8
+ /** Resolved holiday returned by the API */
3
9
  interface Holiday {
4
- /** ISO date: YYYY-MM-DD */
5
10
  date: string;
6
- /** Holiday name in Spanish (as in BOE) */
7
11
  name: string;
8
- /** Region code if scoped to a region (e.g. "CN"). */
12
+ scope: HolidayScope;
9
13
  region?: RegionCode;
10
- /** Region name (e.g. "Canarias") */
11
14
  regionName?: string;
12
- /** "national" = common to all regions. "regional" = chosen/managed by the region. */
13
- scope: HolidayScope;
14
- /** BOE id (useful for traceability) */
15
- source?: string;
15
+ province?: string;
16
+ locality?: string;
16
17
  }
18
+ /** Local holidays grouped by province */
19
+ interface ProvinceSource {
20
+ localities: Record<string, HolidayEntry[]>;
21
+ }
22
+ /** Region source data */
23
+ interface RegionSource {
24
+ regionName: string;
25
+ regional: HolidayEntry[];
26
+ provinces?: Record<string, ProvinceSource>;
27
+ }
28
+ /** Source dataset for a given year */
17
29
  interface HolidaysDataset {
18
- source: string;
19
30
  year: number;
20
31
  generated_at?: string;
21
- national: Array<{
22
- date: string;
23
- name: string;
24
- scope: "national";
25
- }>;
26
- regions: Record<RegionCode, {
27
- regionName: string;
28
- regional: Array<{
29
- date: string;
30
- name: string;
31
- scope: "regional";
32
- }>;
33
- }>;
32
+ national: HolidayEntry[];
33
+ regions: Record<RegionCode, RegionSource>;
34
34
  }
35
35
 
36
36
  declare function getAllHolidays(year?: number): Holiday[];
37
37
  declare function getNationalHolidays(year?: number): Holiday[];
38
38
  declare function getRegionalHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
39
- declare function getAllHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
39
+ /**
40
+ * Local holidays for a region (resolved from provinces/localities)
41
+ */
42
+ declare function getLocalHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
43
+ /**
44
+ * Local holidays filtered by province (province key as stored in the dataset).
45
+ */
46
+ declare function getLocalHolidaysByProvince(region: RegionCode, province: string, year?: number): Holiday[];
47
+ /**
48
+ * Checks if a date is a holiday in Spain.
49
+ * - Without region: checks only national holidays.
50
+ * - With region: checks national + regional + local holidays for that region.
51
+ */
40
52
  declare function isHoliday(date: string | Date, region?: RegionCode, year?: number): boolean;
53
+ /**
54
+ * Checks if a date is a LOCAL (municipal) holiday.
55
+ * Province and locality must match the dataset keys exactly.
56
+ */
57
+ declare function isLocalHoliday(date: string | Date, region: RegionCode, province: string, locality: string, year?: number): boolean;
58
+ declare function getAllHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
41
59
  declare function getAllRegions(year?: number): RegionCode[];
42
60
 
43
- export { type Holiday, type HolidaysDataset, type RegionCode, getAllHolidays, getAllHolidaysByRegionCode, getAllRegions, getNationalHolidays, getRegionalHolidaysByRegionCode, isHoliday };
61
+ export { type Holiday, type HolidaysDataset, type RegionCode, getAllHolidays, getAllHolidaysByRegionCode, getAllRegions, getLocalHolidaysByProvince, getLocalHolidaysByRegionCode, getNationalHolidays, getRegionalHolidaysByRegionCode, isHoliday, isLocalHoliday };
package/dist/index.d.ts CHANGED
@@ -1,43 +1,61 @@
1
1
  type RegionCode = "AN" | "AR" | "AS" | "CB" | "CE" | "CL" | "CM" | "CN" | "CT" | "EX" | "GA" | "IB" | "MC" | "MD" | "ML" | "NC" | "PV" | "RI" | "VC";
2
- type HolidayScope = "national" | "regional";
2
+ type HolidayScope = "national" | "regional" | "local";
3
+ /** Entry as stored in the source dataset */
4
+ interface HolidayEntry {
5
+ date: string;
6
+ name: string;
7
+ }
8
+ /** Resolved holiday returned by the API */
3
9
  interface Holiday {
4
- /** ISO date: YYYY-MM-DD */
5
10
  date: string;
6
- /** Holiday name in Spanish (as in BOE) */
7
11
  name: string;
8
- /** Region code if scoped to a region (e.g. "CN"). */
12
+ scope: HolidayScope;
9
13
  region?: RegionCode;
10
- /** Region name (e.g. "Canarias") */
11
14
  regionName?: string;
12
- /** "national" = common to all regions. "regional" = chosen/managed by the region. */
13
- scope: HolidayScope;
14
- /** BOE id (useful for traceability) */
15
- source?: string;
15
+ province?: string;
16
+ locality?: string;
16
17
  }
18
+ /** Local holidays grouped by province */
19
+ interface ProvinceSource {
20
+ localities: Record<string, HolidayEntry[]>;
21
+ }
22
+ /** Region source data */
23
+ interface RegionSource {
24
+ regionName: string;
25
+ regional: HolidayEntry[];
26
+ provinces?: Record<string, ProvinceSource>;
27
+ }
28
+ /** Source dataset for a given year */
17
29
  interface HolidaysDataset {
18
- source: string;
19
30
  year: number;
20
31
  generated_at?: string;
21
- national: Array<{
22
- date: string;
23
- name: string;
24
- scope: "national";
25
- }>;
26
- regions: Record<RegionCode, {
27
- regionName: string;
28
- regional: Array<{
29
- date: string;
30
- name: string;
31
- scope: "regional";
32
- }>;
33
- }>;
32
+ national: HolidayEntry[];
33
+ regions: Record<RegionCode, RegionSource>;
34
34
  }
35
35
 
36
36
  declare function getAllHolidays(year?: number): Holiday[];
37
37
  declare function getNationalHolidays(year?: number): Holiday[];
38
38
  declare function getRegionalHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
39
- declare function getAllHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
39
+ /**
40
+ * Local holidays for a region (resolved from provinces/localities)
41
+ */
42
+ declare function getLocalHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
43
+ /**
44
+ * Local holidays filtered by province (province key as stored in the dataset).
45
+ */
46
+ declare function getLocalHolidaysByProvince(region: RegionCode, province: string, year?: number): Holiday[];
47
+ /**
48
+ * Checks if a date is a holiday in Spain.
49
+ * - Without region: checks only national holidays.
50
+ * - With region: checks national + regional + local holidays for that region.
51
+ */
40
52
  declare function isHoliday(date: string | Date, region?: RegionCode, year?: number): boolean;
53
+ /**
54
+ * Checks if a date is a LOCAL (municipal) holiday.
55
+ * Province and locality must match the dataset keys exactly.
56
+ */
57
+ declare function isLocalHoliday(date: string | Date, region: RegionCode, province: string, locality: string, year?: number): boolean;
58
+ declare function getAllHolidaysByRegionCode(region: RegionCode, year?: number): Holiday[];
41
59
  declare function getAllRegions(year?: number): RegionCode[];
42
60
 
43
- export { type Holiday, type HolidaysDataset, type RegionCode, getAllHolidays, getAllHolidaysByRegionCode, getAllRegions, getNationalHolidays, getRegionalHolidaysByRegionCode, isHoliday };
61
+ export { type Holiday, type HolidaysDataset, type RegionCode, getAllHolidays, getAllHolidaysByRegionCode, getAllRegions, getLocalHolidaysByProvince, getLocalHolidaysByRegionCode, getNationalHolidays, getRegionalHolidaysByRegionCode, isHoliday, isLocalHoliday };