@fin.cx/opendata 4.0.0 → 4.1.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/.smartconfig.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "githost": "gitlab.com",
6
6
  "gitscope": "fin.cx",
7
7
  "gitrepo": "opendata",
8
- "description": "Open business and financial data for TypeScript: register lookups on the German register portal (handelsregister.de) without storage, and stock and crypto prices and fundamentals from several providers.",
8
+ "description": "Open business and financial data for TypeScript: register lookups on the German register portal (handelsregister.de) without storage, the statutory public holidays of the German federal states, and stock and crypto prices and fundamentals from several providers.",
9
9
  "npmPackagename": "@fin.cx/opendata",
10
10
  "license": "MIT",
11
11
  "projectDomain": "fin.cx",
@@ -22,7 +22,10 @@
22
22
  "data retrieval",
23
23
  "stock prices",
24
24
  "cryptocurrency",
25
- "fundamentals"
25
+ "fundamentals",
26
+ "public holidays",
27
+ "Feiertage",
28
+ "working days"
26
29
  ]
27
30
  },
28
31
  "release": {
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/opendata',
6
- version: '4.0.0',
7
- description: 'Open business and financial data for TypeScript: register lookups on the German register portal (handelsregister.de) without storage, and stock and crypto prices and fundamentals from several providers.'
6
+ version: '4.1.0',
7
+ description: 'Open business and financial data for TypeScript: register lookups on the German register portal (handelsregister.de) without storage, the statutory public holidays of the German federal states, and stock and crypto prices and fundamentals from several providers.'
8
8
  };
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDRNQUE0TTtDQUMxTixDQUFBIn0=
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHdRQUF3UTtDQUN0UixDQUFBIn0=
@@ -15,8 +15,12 @@ export interface IParsedRegisterReferenceText {
15
15
  number: string;
16
16
  }
17
17
  /**
18
- * Finds a register court by its code or its name: `H1101`, `Bremen`, `Amtsgericht Bremen`,
19
- * `Berlin (Charlottenburg)` or `Charlottenburg`. Returns undefined unless exactly one court fits.
18
+ * Finds a register court by its code or by its name as the portal or a business prints it: `H1101`,
19
+ * `Bremen`, `AG Bremen`, `Amtsgericht Bremen – Registergericht`, `Registergericht Bremen`,
20
+ * `Handelsregister B des Amtsgerichts Bremen`, `Amtsgericht Frankfurt a. M.`, `Frankfurt (Oder)`,
21
+ * `Kempten (Allgäu)` or `Kempten`, `Freiburg i. Br.`, `AG Berlin` or `Charlottenburg`. Umlauts may
22
+ * be spelled out (`Muenchen`). Returns undefined unless exactly one court fits: a place the list
23
+ * does not know, and `Frankfurt` alone, name no court.
20
24
  */
21
25
  export declare const findRegisterCourt: (codeOrNameArg: string, courtsArg?: readonly IRegisterCourt[]) => IRegisterCourt | undefined;
22
26
  /** returns the canonical register type for `hrb`, `HRB`, `gnr` …, or undefined */
@@ -1,19 +1,94 @@
1
1
  import { registerTypes } from './constants.js';
2
2
  import { registerCourts } from './data.codelists.js';
3
3
  const collapse = (textArg) => textArg.replace(/\s+/g, ' ').trim();
4
- const courtKey = (textArg) => collapse(textArg)
5
- .replace(/^(?:amtsgericht|registergericht|ag)\s+/i, '')
6
- .toLocaleLowerCase('de-DE');
7
- /** the alternative name the portal puts in brackets: `Berlin (Charlottenburg)` → `charlottenburg` */
8
- const courtAliasKey = (nameArg) => {
9
- const bracket = /\(([^()]+)\)\s*$/.exec(nameArg);
10
- return bracket ? courtKey(bracket[1]) : undefined;
4
+ /** German letters as a text without them spells them: `Muenchen` is `München` */
5
+ const spelledOut = { 'ä': 'ae', 'ö': 'oe', 'ü': 'ue', 'ß': 'ss' };
6
+ /** words that name a court or a register rather than its place */
7
+ const courtWords = new Set([
8
+ 'amtsgericht',
9
+ 'amtsgerichts',
10
+ 'ag',
11
+ 'registergericht',
12
+ 'registergerichts',
13
+ 'handelsregister',
14
+ 'genossenschaftsregister',
15
+ 'partnerschaftsregister',
16
+ 'vereinsregister',
17
+ 'gesellschaftsregister',
18
+ 'abteilung',
19
+ 'beim',
20
+ 'bei',
21
+ 'des',
22
+ ]);
23
+ /**
24
+ * The place a printed court name names, as courts are compared: lower case, German letters spelled
25
+ * out, punctuation as spaces, and without the words that name a court or a register or the
26
+ * division of the commercial register. `Handelsregister B des Amtsgerichts Frankfurt a. M.` is
27
+ * `frankfurt a m`.
28
+ */
29
+ const placeKey = (textArg) => {
30
+ const words = textArg
31
+ .normalize('NFC')
32
+ .toLocaleLowerCase('de-DE')
33
+ .replace(/[äöüß]/g, (letterArg) => spelledOut[letterArg] ?? letterArg)
34
+ .split(/[^\p{L}\p{N}]+/u)
35
+ .filter((wordArg) => wordArg !== '');
36
+ return words
37
+ .filter((wordArg, indexArg) => {
38
+ const previous = words[indexArg - 1];
39
+ const division = (previous === 'handelsregister' || previous === 'abteilung') && (wordArg === 'a' || wordArg === 'b');
40
+ return !courtWords.has(wordArg) && !division;
41
+ })
42
+ .join(' ');
11
43
  };
12
44
  /**
13
- * Finds a register court by its code or its name: `H1101`, `Bremen`, `Amtsgericht Bremen`,
14
- * `Berlin (Charlottenburg)` or `Charlottenburg`. Returns undefined unless exactly one court fits.
45
+ * Other names under which the register courts are printed, for courts whose name in the official
46
+ * list carries a qualifier that prints leave out, abbreviate or spell out. Each name here is a name
47
+ * of that court alone. `Frankfurt` without `am Main` or `(Oder)` is a name of neither of the two.
48
+ */
49
+ const printedCourtNames = {
50
+ 'Bad Homburg v.d.H.': ['Bad Homburg', 'Bad Homburg vor der Höhe', 'Bad Homburg v. d. Höhe'],
51
+ 'Berlin (Charlottenburg)': ['Berlin', 'Charlottenburg', 'Charlottenburg (Berlin)'],
52
+ 'Frankfurt am Main': ['Frankfurt a. M.', 'Frankfurt a. Main', 'Frankfurt/M.', 'Frankfurt/Main', 'Frankfurt (Main)'],
53
+ 'Frankfurt (Oder)': ['Frankfurt/O.', 'Frankfurt a. d. O.', 'Frankfurt an der Oder', 'Frankfurt a. d. Oder'],
54
+ 'Freiburg': ['Freiburg im Breisgau', 'Freiburg i. Br.', 'Freiburg/Breisgau', 'Freiburg (Breisgau)'],
55
+ 'Kempten (Allgäu)': ['Kempten'],
56
+ 'Königstein': ['Königstein im Taunus', 'Königstein i. Ts.'],
57
+ 'Landau': ['Landau in der Pfalz', 'Landau i. d. Pfalz', 'Landau/Pfalz'],
58
+ 'Limburg': ['Limburg an der Lahn', 'Limburg a. d. Lahn'],
59
+ 'Ludwigshafen a.Rhein (Ludwigshafen)': ['Ludwigshafen', 'Ludwigshafen am Rhein'],
60
+ 'Offenbach am Main': ['Offenbach', 'Offenbach a. M.'],
61
+ 'Oldenburg (Oldenburg)': ['Oldenburg', 'Oldenburg (Oldb.)', 'Oldenburg i. O.'],
62
+ 'St. Ingbert (St Ingbert)': ['St. Ingbert', 'Sankt Ingbert'],
63
+ 'St. Wendel (St Wendel)': ['St. Wendel', 'Sankt Wendel'],
64
+ 'Weiden i. d. OPf.': ['Weiden', 'Weiden in der Oberpfalz'],
65
+ };
66
+ /** every place key of a list of courts with the courts it names */
67
+ const courtsByPlaceKey = (courtsArg) => {
68
+ const byKey = new Map();
69
+ for (const court of courtsArg) {
70
+ const keys = new Set([court.name, ...(printedCourtNames[court.name] ?? [])].map(placeKey));
71
+ for (const key of keys) {
72
+ if (key !== '') {
73
+ byKey.set(key, [...(byKey.get(key) ?? []), court]);
74
+ }
75
+ }
76
+ }
77
+ return byKey;
78
+ };
79
+ let officialCourtKeys;
80
+ /**
81
+ * Finds a register court by its code or by its name as the portal or a business prints it: `H1101`,
82
+ * `Bremen`, `AG Bremen`, `Amtsgericht Bremen – Registergericht`, `Registergericht Bremen`,
83
+ * `Handelsregister B des Amtsgerichts Bremen`, `Amtsgericht Frankfurt a. M.`, `Frankfurt (Oder)`,
84
+ * `Kempten (Allgäu)` or `Kempten`, `Freiburg i. Br.`, `AG Berlin` or `Charlottenburg`. Umlauts may
85
+ * be spelled out (`Muenchen`). Returns undefined unless exactly one court fits: a place the list
86
+ * does not know, and `Frankfurt` alone, name no court.
15
87
  */
16
88
  export const findRegisterCourt = (codeOrNameArg, courtsArg = registerCourts) => {
89
+ if (typeof codeOrNameArg !== 'string') {
90
+ return undefined;
91
+ }
17
92
  const text = collapse(codeOrNameArg);
18
93
  if (!text) {
19
94
  return undefined;
@@ -22,16 +97,11 @@ export const findRegisterCourt = (codeOrNameArg, courtsArg = registerCourts) =>
22
97
  if (byCode) {
23
98
  return byCode;
24
99
  }
25
- const key = courtKey(text);
26
- const byName = courtsArg.filter((courtArg) => courtKey(courtArg.name) === key);
27
- if (byName.length === 1) {
28
- return byName[0];
29
- }
30
- if (byName.length > 1) {
31
- return undefined;
32
- }
33
- const byAlias = courtsArg.filter((courtArg) => courtAliasKey(courtArg.name) === key);
34
- return byAlias.length === 1 ? byAlias[0] : undefined;
100
+ const keys = courtsArg === registerCourts
101
+ ? (officialCourtKeys ??= courtsByPlaceKey(registerCourts))
102
+ : courtsByPlaceKey(courtsArg);
103
+ const courts = keys.get(placeKey(text)) ?? [];
104
+ return courts.length === 1 ? courts[0] : undefined;
35
105
  };
36
106
  /** returns the canonical register type for `hrb`, `HRB`, `gnr` …, or undefined */
37
107
  export const toRegisterType = (textArg) => registerTypes.find((typeArg) => typeArg.toLowerCase() === collapse(textArg).toLowerCase());
@@ -73,4 +143,4 @@ export const parseRegisterReferenceText = (textArg, courtsArg = registerCourts)
73
143
  };
74
144
  /** `Amtsgericht Bremen HRB 35230 HB` */
75
145
  export const formatRegisterReference = (referenceArg) => `Amtsgericht ${referenceArg.court.name} ${referenceArg.type} ${referenceArg.number}`;
76
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmZXJlbmNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2hhbmRlbHNyZWdpc3Rlci9yZWZlcmVuY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFvQnJELE1BQU0sUUFBUSxHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUVsRixNQUFNLFFBQVEsR0FBRyxDQUFDLE9BQWUsRUFBVSxFQUFFLENBQzNDLFFBQVEsQ0FBQyxPQUFPLENBQUM7S0FDZCxPQUFPLENBQUMseUNBQXlDLEVBQUUsRUFBRSxDQUFDO0tBQ3RELGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRWhDLHFHQUFxRztBQUNyRyxNQUFNLGFBQWEsR0FBRyxDQUFDLE9BQWUsRUFBc0IsRUFBRTtJQUM1RCxNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakQsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3BELENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQy9CLGFBQXFCLEVBQ3JCLFlBQXVDLGNBQWMsRUFDekIsRUFBRTtJQUM5QixNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxJ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
146
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmZXJlbmNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2hhbmRlbHNyZWdpc3Rlci9yZWZlcmVuY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFvQnJELE1BQU0sUUFBUSxHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUVsRixpRkFBaUY7QUFDakYsTUFBTSxVQUFVLEdBQXFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0FBRXBHLGtFQUFrRTtBQUNsRSxNQUFNLFVBQVUsR0FBd0IsSUFBSSxHQUFHLENBQUM7SUFDOUMsYUFBYTtJQUNiLGNBQWM7SUFDZCxJQUFJO0lBQ0osaUJBQWlCO0lBQ2pCLGtCQUFrQjtJQUNsQixpQkFBaUI7SUFDakIseUJBQXlCO0lBQ3pCLHdCQUF3QjtJQUN4QixpQkFBaUI7SUFDakIsdUJBQXVCO0lBQ3ZCLFdBQVc7SUFDWCxNQUFNO0lBQ04sS0FBSztJQUNMLEtBQUs7Q0FDTixDQUFDLENBQUM7QUFFSDs7Ozs7R0FLRztBQUNILE1BQU0sUUFBUSxHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUU7SUFDM0MsTUFBTSxLQUFLLEdBQUcsT0FBTztTQUNsQixTQUFTLENBQUMsS0FBSyxDQUFDO1NBQ2hCLGlCQUFpQixDQUFDLE9BQU8sQ0FBQztTQUMxQixPQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLElBQUksU0FBUyxDQUFDO1NBQ3JFLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztTQUN4QixNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN2QyxPQUFPLEtBQUs7U0FDVCxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUU7UUFDNUIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLFFBQVEsR0FBRyxDQUFDLFFBQVEsS0FBSyxpQkFBaUIsSUFBSSxRQUFRLEtBQUssV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLEtBQUssR0FBRyxJQUFJLE9BQU8sS0FBSyxHQUFHLENBQUMsQ0FBQztRQUN0SCxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUMvQyxDQUFDLENBQUM7U0FDRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixDQUFDLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBZ0Q7SUFDckUsb0JBQW9CLEVBQUUsQ0FBQyxhQUFhLEVBQUUsMEJBQTBCLEVBQUUsd0JBQXdCLENBQUM7SUFDM0YseUJBQXlCLEVBQUUsQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUseUJBQXlCLENBQUM7SUFDbEYsbUJBQW1CLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLENBQUM7SUFDbkgsa0JBQWtCLEVBQUUsQ0FBQyxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsdUJBQXVCLEVBQUUsc0JBQXNCLENBQUM7SUFDM0csVUFBVSxFQUFFLENBQUMsc0JBQXNCLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLENBQUM7SUFDbkcsa0JBQWtCLEVBQUUsQ0FBQyxTQUFTLENBQUM7SUFDL0IsWUFBWSxFQUFFLENBQUMsc0JBQXNCLEVBQUUsbUJBQW1CLENBQUM7SUFDM0QsUUFBUSxFQUFFLENBQUMscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsY0FBYyxDQUFDO0lBQ3ZFLFNBQVMsRUFBRSxDQUFDLHFCQUFxQixFQUFFLG9CQUFvQixDQUFDO0lBQ3hELHFDQUFxQyxFQUFFLENBQUMsY0FBYyxFQUFFLHVCQUF1QixDQUFDO0lBQ2hGLG1CQUFtQixFQUFFLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDO0lBQ3JELHVCQUF1QixFQUFFLENBQUMsV0FBVyxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixDQUFDO0lBQzlFLDBCQUEwQixFQUFFLENBQUMsYUFBYSxFQUFFLGVBQWUsQ0FBQztJQUM1RCx3QkFBd0IsRUFBRSxDQUFDLFlBQVksRUFBRSxjQUFjLENBQUM7SUFDeEQsbUJBQW1CLEVBQUUsQ0FBQyxRQUFRLEVBQUUseUJBQXlCLENBQUM7Q0FDM0QsQ0FBQztBQUVGLG1FQUFtRTtBQUNuRSxNQUFNLGdCQUFnQixHQUFHLENBQUMsU0FBb0MsRUFBa0QsRUFBRTtJQUNoSCxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztJQUNsRCxLQUFLLE1BQU0sS0FBSyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzlCLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDM0YsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixJQUFJLEdBQUcsS0FBSyxFQUFFLEVBQUUsQ0FBQztnQkFDZixLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDckQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDLENBQUM7QUFFRixJQUFJLGlCQUE2RSxDQUFDO0FBRWxGOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUMvQixhQUFxQixFQUNyQixZQUF1QyxjQUFjLEVBQ3pCLEVBQUU7SUFDOUIsSUFBSSxPQUFPLGFBQWEsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN0QyxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3JDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNWLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ2hHLElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQ1IsU0FBUyxLQUFLLGNBQWM7UUFDMUIsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEtBQUssZ0JBQWdCLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUQsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlDLE9BQU8sTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3JELENBQUMsQ0FBQztBQUVGLGtGQUFrRjtBQUNsRixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxPQUFlLEVBQTZCLEVBQUUsQ0FDM0UsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0FBRTdGLDhFQUE4RTtBQUM5RSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLE9BQWUsRUFBb0MsRUFBRTtJQUN2RixNQUFNLEtBQUssR0FBRyxzQ0FBc0MsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDN0UsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUM3RyxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLFFBQThCLEVBQVUsRUFBRSxDQUM3RSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO0FBRTlFOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxDQUN4QyxPQUFlLEVBQ2YsWUFBdUMsY0FBYyxFQUNYLEVBQUU7SUFDNUMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9CLE1BQU0sS0FBSyxHQUNULDZJQUE2SSxDQUFDLElBQUksQ0FDaEosSUFBSSxDQUNMLENBQUM7SUFDSixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sTUFBTSxHQUFHLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNyQixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUQsTUFBTSxNQUFNLEdBQWlDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQzVGLElBQUksU0FBUyxFQUFFLENBQUM7UUFDZCxNQUFNLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUM3QixNQUFNLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDdEQsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBRUYsd0NBQXdDO0FBQ3hDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsWUFBZ0MsRUFBVSxFQUFFLENBQ2xGLGVBQWUsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksWUFBWSxDQUFDLElBQUksSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMifQ==
@@ -0,0 +1,32 @@
1
+ import type { IGermanState, IPublicHoliday, IWorkingDayOptions, TGermanStateCode, TIsoDate } from './interfaces.js';
2
+ /**
3
+ * Easter Sunday of a year of the Gregorian calendar, by the algorithm of Meeus, Jones and
4
+ * Butcher. The Easter-based holidays follow from it.
5
+ */
6
+ export declare const easterSunday: (yearArg: number) => TIsoDate;
7
+ /**
8
+ * The statutory public holidays of a state in a year, in the order of their dates. Regional
9
+ * holidays are included with `scope: 'regional'` and the part of the state they apply to.
10
+ */
11
+ export declare const getPublicHolidays: (yearArg: number, stateArg: TGermanStateCode) => IPublicHoliday[];
12
+ /** The statutory public holidays of a state on a date, regional ones included. */
13
+ export declare const getPublicHolidaysOn: (dateArg: TIsoDate, stateArg: TGermanStateCode) => IPublicHoliday[];
14
+ /** Whether a date is a statutory public holiday in a state. */
15
+ export declare const isPublicHoliday: (dateArg: TIsoDate, stateArg: TGermanStateCode, optionsArg: IWorkingDayOptions) => boolean;
16
+ /**
17
+ * Whether a date is a working day in a state in the sense of § 193 BGB: neither a Saturday, nor a
18
+ * Sunday, nor a statutory public holiday.
19
+ */
20
+ export declare const isWorkingDay: (dateArg: TIsoDate, stateArg: TGermanStateCode, optionsArg: IWorkingDayOptions) => boolean;
21
+ /** The first working day after a date (§ 193 BGB: not a Saturday, Sunday or public holiday). */
22
+ export declare const nextWorkingDay: (dateArg: TIsoDate, stateArg: TGermanStateCode, optionsArg: IWorkingDayOptions) => TIsoDate;
23
+ /**
24
+ * The date itself when it is a working day, otherwise the next working day: the day that takes the
25
+ * place of a fixed day or of the last day of a period under § 193 BGB.
26
+ */
27
+ export declare const workingDayOnOrAfter: (dateArg: TIsoDate, stateArg: TGermanStateCode, optionsArg: IWorkingDayOptions) => TIsoDate;
28
+ /**
29
+ * The federal state for a code or a name: `DE-BY`, `BY` or `Bayern`, compared without regard to
30
+ * case and surrounding whitespace.
31
+ */
32
+ export declare const findGermanState: (valueArg: string) => IGermanState | undefined;
@@ -0,0 +1,200 @@
1
+ import { HolidayCalendarError } from './classes.holidaycalendarerror.js';
2
+ import { germanStates, holidayCalendarFirstYear, holidayRules } from './data.holidays.js';
3
+ const dayMs = 86_400_000;
4
+ const lastYear = 9999;
5
+ const pad = (valueArg, lengthArg) => String(valueArg).padStart(lengthArg, '0');
6
+ const toIsoDate = (utcArg) => {
7
+ const date = new Date(utcArg);
8
+ return `${pad(date.getUTCFullYear(), 4)}-${pad(date.getUTCMonth() + 1, 2)}-${pad(date.getUTCDate(), 2)}`;
9
+ };
10
+ const utcOf = (yearArg, monthArg, dayArg) => {
11
+ const date = new Date(0);
12
+ date.setUTCFullYear(yearArg, monthArg - 1, dayArg);
13
+ date.setUTCHours(0, 0, 0, 0);
14
+ return date.getTime();
15
+ };
16
+ const checkYear = (yearArg) => {
17
+ if (!Number.isInteger(yearArg) || yearArg < holidayCalendarFirstYear || yearArg > lastYear) {
18
+ throw new HolidayCalendarError('unsupported_year', `The holiday calendar answers for the years ${holidayCalendarFirstYear} to ${lastYear}, not for ${String(yearArg)}.`);
19
+ }
20
+ };
21
+ const parseIsoDate = (dateArg) => {
22
+ const match = typeof dateArg === 'string' ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateArg) : null;
23
+ if (!match) {
24
+ throw new HolidayCalendarError('invalid_date', `A date is written YYYY-MM-DD; ${JSON.stringify(dateArg)} is not.`);
25
+ }
26
+ const year = Number(match[1]);
27
+ const month = Number(match[2]);
28
+ const day = Number(match[3]);
29
+ checkYear(year);
30
+ const utc = utcOf(year, month, day);
31
+ if (toIsoDate(utc) !== dateArg) {
32
+ throw new HolidayCalendarError('invalid_date', `${dateArg} is not a date of the calendar.`);
33
+ }
34
+ return { year, utc };
35
+ };
36
+ const checkState = (stateArg) => {
37
+ if (!germanStates.some((stateEntry) => stateEntry.code === stateArg)) {
38
+ throw new HolidayCalendarError('unknown_state', `${JSON.stringify(stateArg)} is not the ISO 3166-2 code of a German federal state, such as DE-BY.`);
39
+ }
40
+ };
41
+ const checkOptions = (optionsArg) => {
42
+ const policy = optionsArg?.regionalHolidays;
43
+ if (policy !== 'count' && policy !== 'ignore') {
44
+ throw new HolidayCalendarError('invalid_options', 'Say how regional holidays are treated: { regionalHolidays: "count" } or { regionalHolidays: "ignore" }.');
45
+ }
46
+ };
47
+ /**
48
+ * Easter Sunday of a year of the Gregorian calendar, by the algorithm of Meeus, Jones and
49
+ * Butcher. The Easter-based holidays follow from it.
50
+ */
51
+ export const easterSunday = (yearArg) => {
52
+ checkYear(yearArg);
53
+ return toIsoDate(easterUtc(yearArg));
54
+ };
55
+ const easterUtc = (yearArg) => {
56
+ const a = yearArg % 19;
57
+ const b = Math.floor(yearArg / 100);
58
+ const c = yearArg % 100;
59
+ const d = Math.floor(b / 4);
60
+ const e = b % 4;
61
+ const f = Math.floor((b + 8) / 25);
62
+ const g = Math.floor((b - f + 1) / 3);
63
+ const h = (19 * a + b - d - g + 15) % 30;
64
+ const i = Math.floor(c / 4);
65
+ const k = c % 4;
66
+ const l = (32 + 2 * e + 2 * i - h - k) % 7;
67
+ const m = Math.floor((a + 11 * h + 22 * l) / 451);
68
+ const month = Math.floor((h + l - 7 * m + 114) / 31);
69
+ const day = ((h + l - 7 * m + 114) % 31) + 1;
70
+ return utcOf(yearArg, month, day);
71
+ };
72
+ /** the Wednesday before the last Sunday before the first Sunday of Advent (16 to 22 November) */
73
+ const bussUndBettagUtc = (yearArg) => {
74
+ const christmasEve = utcOf(yearArg, 12, 24);
75
+ const fourthAdvent = christmasEve - new Date(christmasEve).getUTCDay() * dayMs;
76
+ const firstAdvent = fourthAdvent - 21 * dayMs;
77
+ return firstAdvent - 11 * dayMs;
78
+ };
79
+ const dateOf = (ruleArg, yearArg) => {
80
+ switch (ruleArg.kind) {
81
+ case 'fixed':
82
+ return utcOf(yearArg, ruleArg.month, ruleArg.day);
83
+ case 'easter':
84
+ return easterUtc(yearArg) + ruleArg.offset * dayMs;
85
+ case 'buss-und-bettag':
86
+ return bussUndBettagUtc(yearArg);
87
+ }
88
+ };
89
+ const appliesIn = (ruleArg, yearArg) => (ruleArg.onlyYear === undefined || ruleArg.onlyYear === yearArg) &&
90
+ (ruleArg.fromYear === undefined || yearArg >= ruleArg.fromYear);
91
+ const holidaysByYearAndState = new Map();
92
+ const holidaysOf = (yearArg, stateArg) => {
93
+ const key = `${yearArg}:${stateArg}`;
94
+ const known = holidaysByYearAndState.get(key);
95
+ if (known) {
96
+ return known;
97
+ }
98
+ const holidays = holidayRules
99
+ .filter((ruleArg) => ruleArg.state === stateArg && appliesIn(ruleArg, yearArg))
100
+ .map((ruleArg) => ({ utc: dateOf(ruleArg.date, yearArg), rule: ruleArg }))
101
+ .sort((leftArg, rightArg) => leftArg.utc - rightArg.utc)
102
+ .map(({ utc, rule }) => {
103
+ const holiday = {
104
+ date: toIsoDate(utc),
105
+ id: rule.id,
106
+ name: rule.name,
107
+ state: rule.state,
108
+ scope: rule.scope,
109
+ legalBasis: rule.legalBasis,
110
+ };
111
+ if (rule.region !== undefined) {
112
+ holiday.region = rule.region;
113
+ }
114
+ return Object.freeze(holiday);
115
+ });
116
+ const frozen = Object.freeze(holidays);
117
+ holidaysByYearAndState.set(key, frozen);
118
+ return frozen;
119
+ };
120
+ /**
121
+ * The statutory public holidays of a state in a year, in the order of their dates. Regional
122
+ * holidays are included with `scope: 'regional'` and the part of the state they apply to.
123
+ */
124
+ export const getPublicHolidays = (yearArg, stateArg) => {
125
+ checkYear(yearArg);
126
+ checkState(stateArg);
127
+ return [...holidaysOf(yearArg, stateArg)];
128
+ };
129
+ /** The statutory public holidays of a state on a date, regional ones included. */
130
+ export const getPublicHolidaysOn = (dateArg, stateArg) => {
131
+ const day = parseIsoDate(dateArg);
132
+ checkState(stateArg);
133
+ return holidaysOf(day.year, stateArg).filter((holidayArg) => holidayArg.date === dateArg);
134
+ };
135
+ const isHolidayUtc = (utcArg, stateArg, optionsArg) => {
136
+ const date = toIsoDate(utcArg);
137
+ const year = new Date(utcArg).getUTCFullYear();
138
+ checkYear(year);
139
+ return holidaysOf(year, stateArg).some((holidayArg) => holidayArg.date === date && (holidayArg.scope === 'state' || optionsArg.regionalHolidays === 'count'));
140
+ };
141
+ const isWorkingDayUtc = (utcArg, stateArg, optionsArg) => {
142
+ const weekday = new Date(utcArg).getUTCDay();
143
+ return weekday !== 0 && weekday !== 6 && !isHolidayUtc(utcArg, stateArg, optionsArg);
144
+ };
145
+ /** Whether a date is a statutory public holiday in a state. */
146
+ export const isPublicHoliday = (dateArg, stateArg, optionsArg) => {
147
+ const day = parseIsoDate(dateArg);
148
+ checkState(stateArg);
149
+ checkOptions(optionsArg);
150
+ return isHolidayUtc(day.utc, stateArg, optionsArg);
151
+ };
152
+ /**
153
+ * Whether a date is a working day in a state in the sense of § 193 BGB: neither a Saturday, nor a
154
+ * Sunday, nor a statutory public holiday.
155
+ */
156
+ export const isWorkingDay = (dateArg, stateArg, optionsArg) => {
157
+ const day = parseIsoDate(dateArg);
158
+ checkState(stateArg);
159
+ checkOptions(optionsArg);
160
+ return isWorkingDayUtc(day.utc, stateArg, optionsArg);
161
+ };
162
+ /** The first working day after a date (§ 193 BGB: not a Saturday, Sunday or public holiday). */
163
+ export const nextWorkingDay = (dateArg, stateArg, optionsArg) => {
164
+ const day = parseIsoDate(dateArg);
165
+ checkState(stateArg);
166
+ checkOptions(optionsArg);
167
+ let utc = day.utc + dayMs;
168
+ while (!isWorkingDayUtc(utc, stateArg, optionsArg)) {
169
+ utc += dayMs;
170
+ }
171
+ return toIsoDate(utc);
172
+ };
173
+ /**
174
+ * The date itself when it is a working day, otherwise the next working day: the day that takes the
175
+ * place of a fixed day or of the last day of a period under § 193 BGB.
176
+ */
177
+ export const workingDayOnOrAfter = (dateArg, stateArg, optionsArg) => {
178
+ const day = parseIsoDate(dateArg);
179
+ checkState(stateArg);
180
+ checkOptions(optionsArg);
181
+ let utc = day.utc;
182
+ while (!isWorkingDayUtc(utc, stateArg, optionsArg)) {
183
+ utc += dayMs;
184
+ }
185
+ return toIsoDate(utc);
186
+ };
187
+ /**
188
+ * The federal state for a code or a name: `DE-BY`, `BY` or `Bayern`, compared without regard to
189
+ * case and surrounding whitespace.
190
+ */
191
+ export const findGermanState = (valueArg) => {
192
+ if (typeof valueArg !== 'string') {
193
+ return undefined;
194
+ }
195
+ const value = valueArg.trim().toLocaleLowerCase('de-DE');
196
+ return germanStates.find((stateArg) => stateArg.code.toLowerCase() === value ||
197
+ stateArg.code.slice(3).toLowerCase() === value ||
198
+ stateArg.name.toLocaleLowerCase('de-DE') === value);
199
+ };
200
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9ob2xpZGF5cy9jYWxlbmRhci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLHdCQUF3QixFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBVTFGLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQztBQUN6QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUM7QUFRdEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFnQixFQUFFLFNBQWlCLEVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBRXZHLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBYyxFQUFZLEVBQUU7SUFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUIsT0FBTyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQzNHLENBQUMsQ0FBQztBQUVGLE1BQU0sS0FBSyxHQUFHLENBQUMsT0FBZSxFQUFFLFFBQWdCLEVBQUUsTUFBYyxFQUFVLEVBQUU7SUFDMUUsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNuRCxJQUFJLENBQUMsV0FBVyxD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
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Why a question to the holiday calendar was refused:
3
+ * - `invalid_date`: the value is not a calendar date written `YYYY-MM-DD`;
4
+ * - `unsupported_year`: the year lies before the first year the calendar answers for (2018) or
5
+ * after 9999;
6
+ * - `unknown_state`: the value is not the code of a German federal state;
7
+ * - `invalid_options`: the options do not say how to treat regional holidays.
8
+ */
9
+ export type THolidayCalendarErrorCode = 'invalid_date' | 'unsupported_year' | 'unknown_state' | 'invalid_options';
10
+ /** The typed error of the holiday calendar. */
11
+ export declare class HolidayCalendarError extends Error {
12
+ readonly code: THolidayCalendarErrorCode;
13
+ constructor(code: THolidayCalendarErrorCode, message: string);
14
+ }
@@ -0,0 +1,10 @@
1
+ /** The typed error of the holiday calendar. */
2
+ export class HolidayCalendarError extends Error {
3
+ code;
4
+ constructor(code, message) {
5
+ super(message);
6
+ this.name = 'HolidayCalendarError';
7
+ this.code = code;
8
+ }
9
+ }
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ob2xpZGF5Y2FsZW5kYXJlcnJvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2hvbGlkYXlzL2NsYXNzZXMuaG9saWRheWNhbGVuZGFyZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVUEsK0NBQStDO0FBQy9DLE1BQU0sT0FBTyxvQkFBcUIsU0FBUSxLQUFLO0lBQzdCLElBQUksQ0FBNEI7SUFFaEQsWUFBWSxJQUErQixFQUFFLE9BQWU7UUFDMUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxzQkFBc0IsQ0FBQztRQUNuQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0NBQ0YifQ==
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The statutory public holidays of the German federal states, taken from the holiday laws of the
3
+ * states (Feiertagsgesetze) and, for 3 October, from Art. 2 Abs. 2 of the Unification Treaty
4
+ * (Einigungsvertrag). The provisions were read on 2026-09-24 in the official law portals of the
5
+ * states; the readme lists them with their links.
6
+ *
7
+ * The rules cover the years from 2018 on. Every change of a state's list since then is recorded
8
+ * with the year it first applies: Reformationstag in Bremen, Hamburg, Niedersachsen and
9
+ * Schleswig-Holstein (2018), Frauentag in Berlin (2019) and Mecklenburg-Vorpommern (2023),
10
+ * Weltkindertag in Thüringen (2019), and the one-off holidays of Berlin (2020, 2025, 2028).
11
+ */
12
+ import type { IGermanState, TGermanStateCode, TPublicHolidayId, TPublicHolidayScope } from './interfaces.js';
13
+ /** the first year the calendar answers for */
14
+ export declare const holidayCalendarFirstYear = 2018;
15
+ /** the day the holiday laws were read; later changes need a new release */
16
+ export declare const holidayLawsReadOn = "2026-09-24";
17
+ export declare const germanStates: readonly IGermanState[];
18
+ /** how the date of a holiday follows from the year */
19
+ export type THolidayDateRule = {
20
+ kind: 'fixed';
21
+ month: number;
22
+ day: number;
23
+ }
24
+ /** days after Easter Sunday; negative before it */
25
+ | {
26
+ kind: 'easter';
27
+ offset: number;
28
+ }
29
+ /** the Wednesday before the last Sunday before the first Sunday of Advent */
30
+ | {
31
+ kind: 'buss-und-bettag';
32
+ };
33
+ export interface IHolidayRule {
34
+ id: TPublicHolidayId;
35
+ name: string;
36
+ date: THolidayDateRule;
37
+ state: TGermanStateCode;
38
+ scope: TPublicHolidayScope;
39
+ region?: string;
40
+ legalBasis: string;
41
+ /** the first year the holiday applies */
42
+ fromYear?: number;
43
+ /** the only year a one-off holiday applies */
44
+ onlyYear?: number;
45
+ }
46
+ export declare const holidayRules: readonly IHolidayRule[];