@fin.cx/opendata 4.5.0 → 4.7.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.
Files changed (42) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/cpi/classes.bundesbankcpiclient.js +1 -1
  3. package/dist_ts/cpi/classes.cpierror.js +1 -1
  4. package/dist_ts/cpi/constants.d.ts +2 -2
  5. package/dist_ts/cpi/indexmath.js +1 -1
  6. package/dist_ts/handelsregister/classes.handelsregisterclient.d.ts +8 -2
  7. package/dist_ts/handelsregister/classes.handelsregisterclient.js +14 -5
  8. package/dist_ts/handelsregister/classes.handelsregistererror.d.ts +3 -1
  9. package/dist_ts/handelsregister/classes.handelsregistererror.js +1 -1
  10. package/dist_ts/handelsregister/classes.portalsession.d.ts +19 -3
  11. package/dist_ts/handelsregister/classes.portalsession.js +67 -9
  12. package/dist_ts/handelsregister/classes.slidingwindowgate.js +1 -1
  13. package/dist_ts/handelsregister/interfaces.d.ts +9 -2
  14. package/dist_ts/handelsregister/parse.searchresults.js +1 -1
  15. package/dist_ts/handelsregister/references.js +1 -1
  16. package/dist_ts/holidays/calendar.d.ts +13 -1
  17. package/dist_ts/holidays/calendar.js +52 -1
  18. package/dist_ts/holidays/classes.holidaycalendarerror.d.ts +4 -1
  19. package/dist_ts/holidays/classes.holidaycalendarerror.js +1 -1
  20. package/dist_ts/holidays/data.holidays.js +1 -1
  21. package/dist_ts/holidays/index.d.ts +1 -1
  22. package/dist_ts/holidays/index.js +2 -2
  23. package/dist_ts/holidays/interfaces.d.ts +2 -0
  24. package/dist_ts/paths.js +1 -1
  25. package/dist_ts/stocks/providers/provider.coingecko.js +1 -1
  26. package/dist_ts/stocks/providers/provider.marketstack.js +1 -1
  27. package/dist_ts/stocks/providers/provider.yahoo.js +1 -1
  28. package/dist_ts/vatid/classes.evatrclient.js +1 -1
  29. package/dist_ts/vatid/classes.viesclient.js +1 -1
  30. package/dist_ts/vatid/constants.d.ts +2 -2
  31. package/dist_ts/vatid/request.d.ts +1 -1
  32. package/package.json +5 -5
  33. package/readme.md +30 -3
  34. package/ts/00_commitinfo_data.ts +1 -1
  35. package/ts/handelsregister/classes.handelsregisterclient.ts +18 -4
  36. package/ts/handelsregister/classes.handelsregistererror.ts +3 -0
  37. package/ts/handelsregister/classes.portalsession.ts +78 -9
  38. package/ts/handelsregister/interfaces.ts +9 -2
  39. package/ts/holidays/calendar.ts +73 -0
  40. package/ts/holidays/classes.holidaycalendarerror.ts +10 -1
  41. package/ts/holidays/index.ts +2 -0
  42. package/ts/holidays/interfaces.ts +3 -0
@@ -92,7 +92,10 @@ export interface IRegisterSearchResult {
92
92
  portalNotice?: string;
93
93
  /** epoch ms: when the result list arrived */
94
94
  retrievedAt: number;
95
- /** requests of this call that count against the portal's limit of 60 per hour (always 1) */
95
+ /**
96
+ * requests of this call that count against the portal's limit of 60 per hour: 1, or 2 when the
97
+ * portal dropped the search without an answer and it was sent once more
98
+ */
96
99
  countedRequests: number;
97
100
  notice: IStructuredContentNotice;
98
101
  }
@@ -202,7 +205,11 @@ export interface IRegisterEntry {
202
205
  structuredContent: IRegisterStructuredContent | null;
203
206
  /** epoch ms: when the last answer of the portal arrived */
204
207
  retrievedAt: number;
205
- /** requests of this call that count against the portal's limit: 2, or 1 without structured content */
208
+ /**
209
+ * requests of this call that count against the portal's limit: 2, or 1 without structured content;
210
+ * one more for the search or the retrieval when the portal dropped it without an answer and it was
211
+ * sent once more
212
+ */
206
213
  countedRequests: number;
207
214
  notice: IStructuredContentNotice;
208
215
  }
@@ -7,6 +7,7 @@ import type {
7
7
  IWorkingDayOptions,
8
8
  TGermanStateCode,
9
9
  TIsoDate,
10
+ TIsoMonth,
10
11
  } from './interfaces.js';
11
12
 
12
13
  const dayMs = 86_400_000;
@@ -57,6 +58,17 @@ const parseIsoDate = (dateArg: TIsoDate): ICalendarDay => {
57
58
  return { year, utc };
58
59
  };
59
60
 
61
+ const parseIsoMonth = (monthArg: TIsoMonth): { year: number; month: number } => {
62
+ const match = typeof monthArg === 'string' ? /^(\d{4})-(\d{2})$/.exec(monthArg) : null;
63
+ const month = match ? Number(match[2]) : 0;
64
+ if (!match || month < 1 || month > 12) {
65
+ throw new HolidayCalendarError('invalid_month', `A month is written YYYY-MM; ${JSON.stringify(monthArg)} is not.`);
66
+ }
67
+ const year = Number(match[1]);
68
+ checkYear(year);
69
+ return { year, month };
70
+ };
71
+
60
72
  const checkState = (stateArg: TGermanStateCode): void => {
61
73
  if (!germanStates.some((stateEntry) => stateEntry.code === stateArg)) {
62
74
  throw new HolidayCalendarError(
@@ -189,6 +201,15 @@ const isWorkingDayUtc = (utcArg: number, stateArg: TGermanStateCode, optionsArg:
189
201
  return weekday !== 0 && weekday !== 6 && !isHolidayUtc(utcArg, stateArg, optionsArg);
190
202
  };
191
203
 
204
+ /** 24 and 31 December, the days the Deutsche Bundesbank closes besides the statutory holidays */
205
+ const isBundesbankClosingDayUtc = (utcArg: number): boolean => {
206
+ const date = new Date(utcArg);
207
+ return date.getUTCMonth() === 11 && (date.getUTCDate() === 24 || date.getUTCDate() === 31);
208
+ };
209
+
210
+ const isBankWorkingDayUtc = (utcArg: number, stateArg: TGermanStateCode, optionsArg: IWorkingDayOptions): boolean =>
211
+ isWorkingDayUtc(utcArg, stateArg, optionsArg) && !isBundesbankClosingDayUtc(utcArg);
212
+
192
213
  /** Whether a date is a statutory public holiday in a state. */
193
214
  export const isPublicHoliday = (
194
215
  dateArg: TIsoDate,
@@ -212,6 +233,58 @@ export const isWorkingDay = (dateArg: TIsoDate, stateArg: TGermanStateCode, opti
212
233
  return isWorkingDayUtc(day.utc, stateArg, optionsArg);
213
234
  };
214
235
 
236
+ /**
237
+ * Whether a date is a bank working day (Bankarbeitstag) in a state: neither a Saturday, nor a
238
+ * Sunday, nor a statutory public holiday, nor 24 or 31 December, on which the Deutsche Bundesbank
239
+ * is closed. These are the days the German social insurance counts the due dates of contributions
240
+ * in, with the holidays of the state where the collecting agency has its seat.
241
+ */
242
+ export const isBankWorkingDay = (
243
+ dateArg: TIsoDate,
244
+ stateArg: TGermanStateCode,
245
+ optionsArg: IWorkingDayOptions,
246
+ ): boolean => {
247
+ const day = parseIsoDate(dateArg);
248
+ checkState(stateArg);
249
+ checkOptions(optionsArg);
250
+ return isBankWorkingDayUtc(day.utc, stateArg, optionsArg);
251
+ };
252
+
253
+ /**
254
+ * The bank working day of a month at a position counted from the month's end: 1 is the last bank
255
+ * working day of the month, 3 the third-last.
256
+ */
257
+ export const nthLastBankWorkingDay = (
258
+ monthArg: TIsoMonth,
259
+ positionArg: number,
260
+ stateArg: TGermanStateCode,
261
+ optionsArg: IWorkingDayOptions,
262
+ ): TIsoDate => {
263
+ const { year, month } = parseIsoMonth(monthArg);
264
+ checkState(stateArg);
265
+ checkOptions(optionsArg);
266
+ if (!Number.isInteger(positionArg) || positionArg < 1) {
267
+ throw new HolidayCalendarError(
268
+ 'invalid_position',
269
+ `A position counted from the end of a month is a whole number from 1 on, not ${String(positionArg)}.`,
270
+ );
271
+ }
272
+ const first = utcOf(year, month, 1);
273
+ let found = 0;
274
+ for (let utc = utcOf(year, month + 1, 0); utc >= first; utc -= dayMs) {
275
+ if (isBankWorkingDayUtc(utc, stateArg, optionsArg)) {
276
+ found += 1;
277
+ if (found === positionArg) {
278
+ return toIsoDate(utc);
279
+ }
280
+ }
281
+ }
282
+ throw new HolidayCalendarError(
283
+ 'invalid_position',
284
+ `${monthArg} has ${found} bank working days in ${stateArg}, fewer than ${positionArg}.`,
285
+ );
286
+ };
287
+
215
288
  /** The first working day after a date (§ 193 BGB: not a Saturday, Sunday or public holiday). */
216
289
  export const nextWorkingDay = (dateArg: TIsoDate, stateArg: TGermanStateCode, optionsArg: IWorkingDayOptions): TIsoDate => {
217
290
  const day = parseIsoDate(dateArg);
@@ -1,12 +1,21 @@
1
1
  /**
2
2
  * Why a question to the holiday calendar was refused:
3
3
  * - `invalid_date`: the value is not a calendar date written `YYYY-MM-DD`;
4
+ * - `invalid_month`: the value is not a calendar month written `YYYY-MM`;
5
+ * - `invalid_position`: the position of a bank working day counted from the end of a month is not
6
+ * a whole number from 1 up to the number of bank working days the month has;
4
7
  * - `unsupported_year`: the year lies before the first year the calendar answers for (2018) or
5
8
  * after 9999;
6
9
  * - `unknown_state`: the value is not the code of a German federal state;
7
10
  * - `invalid_options`: the options do not say how to treat regional holidays.
8
11
  */
9
- export type THolidayCalendarErrorCode = 'invalid_date' | 'unsupported_year' | 'unknown_state' | 'invalid_options';
12
+ export type THolidayCalendarErrorCode =
13
+ | 'invalid_date'
14
+ | 'invalid_month'
15
+ | 'invalid_position'
16
+ | 'unsupported_year'
17
+ | 'unknown_state'
18
+ | 'invalid_options';
10
19
 
11
20
  /** The typed error of the holiday calendar. */
12
21
  export class HolidayCalendarError extends Error {
@@ -11,8 +11,10 @@ export {
11
11
  findGermanState,
12
12
  getPublicHolidays,
13
13
  getPublicHolidaysOn,
14
+ isBankWorkingDay,
14
15
  isPublicHoliday,
15
16
  isWorkingDay,
16
17
  nextWorkingDay,
18
+ nthLastBankWorkingDay,
17
19
  workingDayOnOrAfter,
18
20
  } from './calendar.js';
@@ -27,6 +27,9 @@ export interface IGermanState {
27
27
  /** A plain calendar date, `YYYY-MM-DD`. */
28
28
  export type TIsoDate = string;
29
29
 
30
+ /** A calendar month, `YYYY-MM`. */
31
+ export type TIsoMonth = string;
32
+
30
33
  /** The statutory public holidays the calendar knows. */
31
34
  export type TPublicHolidayId =
32
35
  | 'neujahr'