lib-fints 1.4.8 → 1.5.1

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 (80) hide show
  1. package/README.md +21 -15
  2. package/dist/accountDescriptor.js +65 -0
  3. package/dist/bankAccount.js +8 -0
  4. package/dist/client.js +71 -33
  5. package/dist/config.js +57 -10
  6. package/dist/dataElements/Binary.js +18 -1
  7. package/dist/dialog.js +52 -31
  8. package/dist/electronicStatement.js +1 -0
  9. package/dist/httpClient.js +1 -1
  10. package/dist/index.js +2 -0
  11. package/dist/interactions/balanceInteraction.js +10 -8
  12. package/dist/interactions/creditcardStatementInteraction.js +17 -8
  13. package/dist/interactions/electronicStatementInteraction.js +89 -0
  14. package/dist/interactions/portfolioInteraction.js +19 -11
  15. package/dist/interactions/sepaAccountInteraction.js +11 -8
  16. package/dist/interactions/statementInteractionCAMT.js +14 -8
  17. package/dist/interactions/statementInteractionMT940.js +17 -9
  18. package/dist/message.js +10 -2
  19. package/dist/segments/HIEKA.js +45 -0
  20. package/dist/segments/HIEKAS.js +18 -0
  21. package/dist/segments/HKEKA.js +43 -0
  22. package/dist/segments/HKKAZ.js +1 -1
  23. package/dist/segments/registry.js +6 -0
  24. package/dist/tests/HKEKA.test.js +198 -0
  25. package/dist/tests/accountDescriptor.test.js +99 -0
  26. package/dist/tests/accountReference.test.js +126 -0
  27. package/dist/tests/interactionAccountDescriptor.test.js +153 -0
  28. package/dist/tests/message.test.js +18 -0
  29. package/dist/tests/partedResponse.test.js +181 -0
  30. package/dist/types/accountDescriptor.d.ts +49 -0
  31. package/dist/types/accountDescriptor.d.ts.map +1 -0
  32. package/dist/types/bankAccount.d.ts +13 -0
  33. package/dist/types/bankAccount.d.ts.map +1 -1
  34. package/dist/types/client.d.ts +45 -16
  35. package/dist/types/client.d.ts.map +1 -1
  36. package/dist/types/config.d.ts +27 -6
  37. package/dist/types/config.d.ts.map +1 -1
  38. package/dist/types/dataElements/Binary.d.ts +7 -0
  39. package/dist/types/dataElements/Binary.d.ts.map +1 -1
  40. package/dist/types/dialog.d.ts +14 -0
  41. package/dist/types/dialog.d.ts.map +1 -1
  42. package/dist/types/electronicStatement.d.ts +40 -0
  43. package/dist/types/electronicStatement.d.ts.map +1 -0
  44. package/dist/types/index.d.ts +3 -0
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/dist/types/interactions/balanceInteraction.d.ts +3 -2
  47. package/dist/types/interactions/balanceInteraction.d.ts.map +1 -1
  48. package/dist/types/interactions/creditcardStatementInteraction.d.ts +3 -2
  49. package/dist/types/interactions/creditcardStatementInteraction.d.ts.map +1 -1
  50. package/dist/types/interactions/electronicStatementInteraction.d.ts +34 -0
  51. package/dist/types/interactions/electronicStatementInteraction.d.ts.map +1 -0
  52. package/dist/types/interactions/portfolioInteraction.d.ts +3 -2
  53. package/dist/types/interactions/portfolioInteraction.d.ts.map +1 -1
  54. package/dist/types/interactions/sepaAccountInteraction.d.ts +3 -2
  55. package/dist/types/interactions/sepaAccountInteraction.d.ts.map +1 -1
  56. package/dist/types/interactions/statementInteractionCAMT.d.ts +3 -2
  57. package/dist/types/interactions/statementInteractionCAMT.d.ts.map +1 -1
  58. package/dist/types/interactions/statementInteractionMT940.d.ts +3 -2
  59. package/dist/types/interactions/statementInteractionMT940.d.ts.map +1 -1
  60. package/dist/types/message.d.ts.map +1 -1
  61. package/dist/types/segments/HIEKA.d.ts +52 -0
  62. package/dist/types/segments/HIEKA.d.ts.map +1 -0
  63. package/dist/types/segments/HIEKAS.d.ts +21 -0
  64. package/dist/types/segments/HIEKAS.d.ts.map +1 -0
  65. package/dist/types/segments/HKEKA.d.ts +54 -0
  66. package/dist/types/segments/HKEKA.d.ts.map +1 -0
  67. package/dist/types/segments/HKKAZ.d.ts +2 -2
  68. package/dist/types/segments/HKKAZ.d.ts.map +1 -1
  69. package/dist/types/segments/registry.d.ts.map +1 -1
  70. package/dist/types/tests/HKEKA.test.d.ts +2 -0
  71. package/dist/types/tests/HKEKA.test.d.ts.map +1 -0
  72. package/dist/types/tests/accountDescriptor.test.d.ts +2 -0
  73. package/dist/types/tests/accountDescriptor.test.d.ts.map +1 -0
  74. package/dist/types/tests/accountReference.test.d.ts +2 -0
  75. package/dist/types/tests/accountReference.test.d.ts.map +1 -0
  76. package/dist/types/tests/interactionAccountDescriptor.test.d.ts +2 -0
  77. package/dist/types/tests/interactionAccountDescriptor.test.d.ts.map +1 -0
  78. package/dist/types/tests/partedResponse.test.d.ts +2 -0
  79. package/dist/types/tests/partedResponse.test.d.ts.map +1 -0
  80. package/package.json +2 -2
@@ -0,0 +1,181 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { FinTSConfig } from '../config.js';
3
+ import { Dialog } from '../dialog.js';
4
+ import { StatementInteractionCAMT } from '../interactions/statementInteractionCAMT.js';
5
+ import { CustomerOrderMessage, Message } from '../message.js';
6
+ import { HICAZ } from '../segments/HICAZ.js';
7
+ import { HKCAZ } from '../segments/HKCAZ.js';
8
+ import { registerSegments } from '../segments/registry.js';
9
+ vi.mock('../httpClient.js', () => ({
10
+ HttpClient: class MockHttpClient {
11
+ url;
12
+ debug;
13
+ debugRaw;
14
+ constructor(url, debug = false, debugRaw = false) {
15
+ this.url = url;
16
+ this.debug = debug;
17
+ this.debugRaw = debugRaw;
18
+ }
19
+ sendMessage = vi.fn();
20
+ },
21
+ }));
22
+ registerSegments();
23
+ const CAMT_DESCRIPTOR = 'urn?:iso?:std?:iso?:20022?:tech?:xsd?:camt.052.001.08';
24
+ /**
25
+ * A HICAZ segment as the bank sends it. Every portion of a parted response is a
26
+ * COMPLETE segment — it repeats account and descriptor before carrying its own share
27
+ * of the CAMT documents.
28
+ */
29
+ function hicazText(...camtDocuments) {
30
+ const booked = camtDocuments.map((doc) => `@${doc.length}@${doc}`).join(':');
31
+ return `HICAZ:5:1+DE991234567123456:BANK12+${CAMT_DESCRIPTOR}+${booked}'`;
32
+ }
33
+ function responseMessage(hicaz, withContinuation) {
34
+ const answers = withContinuation
35
+ ? "HIRMG:3:2+0010::Entgegengenommen.+3040::Es liegen weitere Umsaetze vor.:AUFSETZ_1'"
36
+ : "HIRMG:3:2+0010::Entgegengenommen.+0020::Abfrage erfolgreich.'";
37
+ return Message.decode(`${answers}${hicaz}`, HICAZ.Id);
38
+ }
39
+ describe('parted responses (bank answer code 3040)', () => {
40
+ let config;
41
+ let dialog;
42
+ beforeEach(() => {
43
+ const bankingInformation = {
44
+ systemId: 'MOCK_SYSTEM_ID',
45
+ bankMessages: [],
46
+ bpd: {
47
+ version: 1,
48
+ bankId: '12030000',
49
+ bankName: 'Mock Bank',
50
+ countryCode: 280,
51
+ url: 'http://mock.bank.url',
52
+ allowedTransactions: [
53
+ { transId: 'HKCAZ', tanRequired: false, versions: [1] },
54
+ ],
55
+ supportedTanMethods: [],
56
+ availableTanMethodIds: [],
57
+ maxTransactionsPerMessage: 1,
58
+ supportedLanguages: [],
59
+ supportedHbciVersions: [300],
60
+ },
61
+ };
62
+ config = FinTSConfig.fromBankingInformation('PRODUCT', '1.0', bankingInformation, 'user', 'pin');
63
+ dialog = new Dialog(config);
64
+ });
65
+ it('delivers every portion into the message the caller holds', async () => {
66
+ const first = responseMessage(hicazText('<Doc>one</Doc>'), true);
67
+ const second = responseMessage(hicazText('<Doc>two</Doc>', '<Doc>three</Doc>'), false);
68
+ vi.mocked(dialog.httpClient.sendMessage).mockResolvedValueOnce(second);
69
+ const interaction = new StatementInteractionCAMT('123');
70
+ const request = new CustomerOrderMessage(HKCAZ.Id, HICAZ.Id);
71
+ request.addSegment({
72
+ header: { segId: HKCAZ.Id, segNr: 0, version: 1 },
73
+ account: { iban: 'DE991234567123456', bic: 'BANK12' },
74
+ acceptedCamtFormats: ['urn:iso:std:iso:20022:tech:xsd:camt.052.001.08'],
75
+ allAccounts: false,
76
+ });
77
+ // biome-ignore lint/suspicious/noExplicitAny: reaching into the private collector on purpose
78
+ await dialog.handlePartedMessages(request, first, interaction);
79
+ // Before the fix this was a single unresolved PARTED segment and everything after
80
+ // the first portion was lost without a trace.
81
+ const segments = first.findAllSegments(HICAZ.Id);
82
+ expect(first.findAllSegments('PARTED')).toHaveLength(0);
83
+ expect(segments).toHaveLength(2);
84
+ expect(segments.flatMap((s) => s.bookedTransactions)).toEqual([
85
+ '<Doc>one</Doc>',
86
+ '<Doc>two</Doc>',
87
+ '<Doc>three</Doc>',
88
+ ]);
89
+ });
90
+ it('leaves an unparted response untouched', async () => {
91
+ const only = responseMessage(hicazText('<Doc>one</Doc>'), false);
92
+ const interaction = new StatementInteractionCAMT('123');
93
+ const request = new CustomerOrderMessage(HKCAZ.Id, HICAZ.Id);
94
+ request.addSegment({
95
+ header: { segId: HKCAZ.Id, segNr: 0, version: 1 },
96
+ account: { iban: 'DE991234567123456', bic: 'BANK12' },
97
+ acceptedCamtFormats: ['urn:iso:std:iso:20022:tech:xsd:camt.052.001.08'],
98
+ allAccounts: false,
99
+ });
100
+ // biome-ignore lint/suspicious/noExplicitAny: reaching into the private collector on purpose
101
+ await dialog.handlePartedMessages(request, only, interaction);
102
+ expect(dialog.httpClient.sendMessage).not.toHaveBeenCalled();
103
+ const segments = only.findAllSegments(HICAZ.Id);
104
+ expect(segments).toHaveLength(1);
105
+ expect(segments[0].bookedTransactions).toEqual(['<Doc>one</Doc>']);
106
+ });
107
+ });
108
+ describe('StatementInteractionCAMT with a parted response', () => {
109
+ it('parses the CAMT documents of every segment, not just the first', () => {
110
+ const camt = (id, amount) => `<?xml version="1.0"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.052.001.08">` +
111
+ `<BkToCstmrAcctRpt><GrpHdr><MsgId>${id}</MsgId><CreDtTm>2026-07-01T10:00:00+02:00</CreDtTm></GrpHdr>` +
112
+ `<Rpt><Id>${id}</Id><Acct><Id><IBAN>DE991234567123456</IBAN></Id><Ccy>EUR</Ccy></Acct>` +
113
+ `<Bal><Tp><CdOrPrtry><Cd>PRCD</Cd></CdOrPrtry></Tp><Amt Ccy="EUR">1000.00</Amt>` +
114
+ `<CdtDbtInd>CRDT</CdtDbtInd><Dt><Dt>2026-06-30</Dt></Dt></Bal>` +
115
+ `<Bal><Tp><CdOrPrtry><Cd>CLBD</Cd></CdOrPrtry></Tp><Amt Ccy="EUR">990.00</Amt>` +
116
+ `<CdtDbtInd>CRDT</CdtDbtInd><Dt><Dt>2026-07-01</Dt></Dt></Bal>` +
117
+ `<Ntry><Amt>${amount}</Amt><CdtDbtInd>DBIT</CdtDbtInd>` +
118
+ `<BookgDt><Dt>2026-07-01</Dt></BookgDt><ValDt><Dt>2026-07-01</Dt></ValDt>` +
119
+ `<AcctSvcrRef>TXN${id}</AcctSvcrRef>` +
120
+ `<NtryDtls><TxDtls><RmtInf><Ustrd>Test ${id}</Ustrd></RmtInf></TxDtls></NtryDtls>` +
121
+ `</Ntry></Rpt></BkToCstmrAcctRpt></Document>`;
122
+ const message = Message.decode(`${hicazText(camt('A', '10.00'))}${hicazText(camt('B', '20.00'))}`);
123
+ expect(message.findAllSegments(HICAZ.Id)).toHaveLength(2);
124
+ const interaction = new StatementInteractionCAMT('123');
125
+ const clientResponse = { statements: [] };
126
+ interaction.handleResponse(message, clientResponse);
127
+ const transactions = clientResponse.statements.flatMap((s) => s.transactions);
128
+ expect(transactions).toHaveLength(2);
129
+ });
130
+ });
131
+ describe('several response segments in one bank message', () => {
132
+ it('resolves every portion, not just the first', async () => {
133
+ // Eine Botschaft mit ZWEI HICAZ-Segmenten. Vorher wurde nur das erste aufgeloest;
134
+ // das zweite blieb als PARTED im Baum und war fuer findAllSegments unsichtbar.
135
+ const answers = "HIRMG:3:2+0010::Entgegengenommen.+0020::Abfrage erfolgreich.'";
136
+ const message = Message.decode(`${answers}${hicazText('<Doc>one</Doc>')}${hicazText('<Doc>two</Doc>')}`, HICAZ.Id);
137
+ expect(message.findAllSegments('PARTED')).toHaveLength(2);
138
+ const dialog = new Dialog(FinTSConfig.fromBankingInformation('PRODUCT', '1.0', {
139
+ systemId: 'X',
140
+ bankMessages: [],
141
+ bpd: {
142
+ version: 1,
143
+ bankId: '12030000',
144
+ bankName: 'Mock',
145
+ countryCode: 280,
146
+ url: 'http://mock.bank.url',
147
+ allowedTransactions: [{ transId: 'HKCAZ', tanRequired: false, versions: [1] }],
148
+ supportedTanMethods: [],
149
+ availableTanMethodIds: [],
150
+ maxTransactionsPerMessage: 1,
151
+ supportedLanguages: [],
152
+ supportedHbciVersions: [300],
153
+ },
154
+ // biome-ignore lint/suspicious/noExplicitAny: schlanker Mock
155
+ }, 'user', 'pin'));
156
+ const request = new CustomerOrderMessage(HKCAZ.Id, HICAZ.Id);
157
+ request.addSegment({
158
+ header: { segId: HKCAZ.Id, segNr: 0, version: 1 },
159
+ account: { iban: 'DE991234567123456', bic: 'BANK12' },
160
+ acceptedCamtFormats: ['urn:iso:std:iso:20022:tech:xsd:camt.052.001.08'],
161
+ allAccounts: false,
162
+ });
163
+ // biome-ignore lint/suspicious/noExplicitAny: private Sammelroutine, absichtlich
164
+ await dialog.handlePartedMessages(request, message, new StatementInteractionCAMT('123'));
165
+ expect(message.findAllSegments('PARTED')).toHaveLength(0);
166
+ const segments = message.findAllSegments(HICAZ.Id);
167
+ expect(segments).toHaveLength(2);
168
+ expect(segments.flatMap((s) => s.bookedTransactions)).toEqual([
169
+ '<Doc>one</Doc>',
170
+ '<Doc>two</Doc>',
171
+ ]);
172
+ });
173
+ it('does not mistake a parameter segment for a response segment', () => {
174
+ // HICAZS begins like HICAZ. Without the colon in the comparison it would be held
175
+ // back as PARTED and never decoded — the same for HIEKAS/HIEKA, HIKAZS/HIKAZ.
176
+ const hicazs = "HICAZS:16:1:4+1+1+0+450:N:N:urn?:iso?:std?:iso?:20022?:tech?:xsd?:camt.052.001.08'";
177
+ const message = Message.decode(hicazs, HICAZ.Id);
178
+ expect(message.findAllSegments('PARTED')).toHaveLength(0);
179
+ expect(message.findAllSegments('HICAZS')).toHaveLength(1);
180
+ });
181
+ });
@@ -0,0 +1,49 @@
1
+ import type { BankAccount } from './bankAccount.js';
2
+ import type { FinTSConfig } from './config.js';
3
+ import type { Account } from './dataGroups/Account.js';
4
+ import type { InternationalAccount } from './dataGroups/InternationalAccount.js';
5
+ /**
6
+ * Builds the account connection ("Kontoverbindung") a segment carries.
7
+ *
8
+ * FinTS has two forms, and segments pick one by version: the national form (KTV,
9
+ * account number + sub-account + bank) and the international one (KTI, which adds
10
+ * IBAN and BIC and makes every field optional). The international form allows the
11
+ * national fields to be present as well, but only where the bank permits it — and
12
+ * the bank says so in the HISPAS parameters, in `nationalAccountAllowed`.
13
+ *
14
+ * Filling both halves regardless is rejected by banks that set the flag to false.
15
+ * Measured at comdirect (BLZ 2004xxxx), same account, same range, same session:
16
+ *
17
+ * IBAN + BIC + number + sub-account + bank → 3010 "Kontonummer ist ungültig", 0 statements
18
+ * IBAN + BIC → 0020 "Auftrag ausgeführt", 19 statements
19
+ * IBAN → 0020 "Auftrag ausgeführt", 19 statements
20
+ * number + sub-account + bank → 3010 "Kontonummer ist ungültig", 0 statements
21
+ *
22
+ * The last line is why this is a rule about the national *fields* rather than about
23
+ * the combination: the bank rejects them in a KTI even when no IBAN accompanies
24
+ * them.
25
+ */
26
+ /**
27
+ * The national form. Built field by field rather than by spreading the account and
28
+ * blanking what does not belong: the data group has exactly these three fields, and
29
+ * saying so is clearer than relying on the encoder to ignore the rest.
30
+ */
31
+ export declare function nationalAccount(account: BankAccount): Account;
32
+ /**
33
+ * The international form. IBAN and BIC always; the national fields only where the
34
+ * bank's HISPAS parameters allow them.
35
+ *
36
+ * An account without an IBAN — a securities account, typically — has nothing else
37
+ * to identify it with, so it keeps the national fields whatever the flag says. A
38
+ * request the bank refuses is more useful than one it cannot resolve at all.
39
+ *
40
+ * A bank that announces no HISPAS at all keeps both halves, exactly as before. The
41
+ * specification would read absent permission as no permission, but this library has
42
+ * already been round that loop: #20 reduced the CAMT descriptor to IBAN and BIC for
43
+ * comdirect, #25 reported Postbank answering "Angaben zur nationalen Kontoverbindung
44
+ * für Identifikation erforderlich", and the reduction was reverted. Only a bank that
45
+ * says `false` gets the shorter form, so no bank that works today can regress on a
46
+ * rule it never stated.
47
+ */
48
+ export declare function internationalAccount(config: FinTSConfig, account: BankAccount): InternationalAccount;
49
+ //# sourceMappingURL=accountDescriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accountDescriptor.d.ts","sourceRoot":"","sources":["../../src/accountDescriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAIjF;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAM7D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,GAClB,oBAAoB,CAgBtB"}
@@ -22,5 +22,18 @@ export type BankAccount = SepaAccount & {
22
22
  limit?: AccountLimit;
23
23
  allowedTransactions?: AllowedTransactions[];
24
24
  };
25
+ /**
26
+ * How a caller names an account.
27
+ *
28
+ * An account number is not by itself unique: FinTS identifies an account by number
29
+ * *and* sub-account id together, and banks use that — a securities account and the
30
+ * current account it settles through commonly share a number and differ only in the
31
+ * sub-account id. Where that happens, a number alone cannot say which one is meant,
32
+ * so the account itself can be passed instead. Take it from
33
+ * `config.bankingInformation.upd.bankAccounts`.
34
+ */
35
+ export type AccountRef = string | BankAccount;
36
+ /** How an account reference reads in an error message. */
37
+ export declare function describeAccount(account: AccountRef): string;
25
38
  export declare function finTsAccountTypeToEnum(accountType: number): AccountType;
26
39
  //# sourceMappingURL=bankAccount.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bankAccount.d.ts","sourceRoot":"","sources":["../../src/bankAccount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,oBAAY,WAAW;IACtB,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,qBAAqB,0BAA0B;IAC/C,mBAAmB,wBAAwB;IAC3C,eAAe,oBAAoB;IACnC,aAAa,kBAAkB;CAC/B;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC5C,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAWvE"}
1
+ {"version":3,"file":"bankAccount.d.ts","sourceRoot":"","sources":["../../src/bankAccount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,oBAAY,WAAW;IACtB,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,qBAAqB,0BAA0B;IAC/C,mBAAmB,wBAAwB;IAC3C,eAAe,oBAAoB;IACnC,aAAa,kBAAkB;CAC/B;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC5C,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,CAAC;AAE9C,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAK3D;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAWvE"}
@@ -1,6 +1,8 @@
1
+ import { type AccountRef } from './bankAccount.js';
1
2
  import { FinTSConfig } from './config.js';
2
3
  import { type AccountBalanceResponse } from './interactions/balanceInteraction.js';
3
4
  import type { StatementResponse } from './interactions/customerInteraction.js';
5
+ import { type ElectronicStatementOptions, type ElectronicStatementResponse } from './interactions/electronicStatementInteraction.js';
4
6
  import type { InitResponse } from './interactions/initDialogInteraction.js';
5
7
  import { type PortfolioResponse } from './interactions/portfolioInteraction.js';
6
8
  import type { TanMethod } from './tanMethod.js';
@@ -42,16 +44,16 @@ export declare class FinTSClient {
42
44
  synchronizeWithTan(tanReference: string, tan?: string): Promise<SynchronizeResponse>;
43
45
  /**
44
46
  * Checks if the bank supports fetching an account balance in general or for the given account number when provided
45
- * @param accountNumber when the account number is provided, checks if the account supports fetching the balance
47
+ * @param account when the account number is provided, checks if the account supports fetching the balance
46
48
  * @returns true if the bank (and account) supports fetching the account balance
47
49
  */
48
- canGetAccountBalance(accountNumber?: string): boolean;
50
+ canGetAccountBalance(account?: AccountRef): boolean;
49
51
  /**
50
52
  * Fetches the account balance for the given account number
51
- * @param accountNumber - the account number to fetch the balance for, must be an account available in the config.baningInformation.UPD.accounts
53
+ * @param account - the account number to fetch the balance for, must be an account available in the config.baningInformation.UPD.accounts
52
54
  * @returns the account balance response
53
55
  */
54
- getAccountBalance(accountNumber: string): Promise<AccountBalanceResponse>;
56
+ getAccountBalance(account: AccountRef): Promise<AccountBalanceResponse>;
55
57
  /**
56
58
  * Continues the account balance fetching when a TAN is required
57
59
  * @param tanReference The TAN reference provided in the first call's response
@@ -61,19 +63,19 @@ export declare class FinTSClient {
61
63
  getAccountBalanceWithTan(tanReference: string, tan?: string): Promise<AccountBalanceResponse>;
62
64
  /**
63
65
  * Checks if the bank supports fetching account statements in general or for the given account number when provided
64
- * @param accountNumber when the account number is provided, checks if the account supports fetching of statements
66
+ * @param account when the account number is provided, checks if the account supports fetching of statements
65
67
  * @returns true if the bank (and account) supports fetching account statements
66
68
  */
67
- canGetAccountStatements(accountNumber?: string): boolean;
69
+ canGetAccountStatements(account?: AccountRef): boolean;
68
70
  /**
69
71
  * Fetches the account statements for the given account number
70
- * @param accountNumber - the account number to fetch the statements for, must be an account available in the config.baningInformation.UPD.accounts
72
+ * @param account - the account number to fetch the statements for, must be an account available in the config.baningInformation.UPD.accounts
71
73
  * @param from - an optional start date of the period to fetch the statements for
72
74
  * @param to - an optional end date of the period to fetch the statements for
73
75
  * @param preferCamt - whether to prefer CAMT format over MT940 when both are supported (default: true)
74
76
  * @returns an account statements response containing an array of statements
75
77
  */
76
- getAccountStatements(accountNumber: string, from?: Date, to?: Date, preferCamt?: boolean): Promise<StatementResponse>;
78
+ getAccountStatements(account: AccountRef, from?: Date, to?: Date, preferCamt?: boolean): Promise<StatementResponse>;
77
79
  /**
78
80
  * Continues the account statements fetching when a TAN is required
79
81
  * @param tanReference The TAN reference provided in the first call's response
@@ -83,19 +85,19 @@ export declare class FinTSClient {
83
85
  getAccountStatementsWithTan(tanReference: string, tan?: string): Promise<StatementResponse>;
84
86
  /**
85
87
  * Checks if the bank supports fetching portfolio information in general or for the given account number when provided
86
- * @param accountNumber when the account number is provided, checks if the account supports fetching of portfolio information
88
+ * @param account when the account number is provided, checks if the account supports fetching of portfolio information
87
89
  * @returns true if the bank (and account) supports fetching portfolio information
88
90
  */
89
- canGetPortfolio(accountNumber?: string): boolean;
91
+ canGetPortfolio(account?: AccountRef): boolean;
90
92
  /**
91
93
  * Fetches the portfolio information for the given depot account number
92
- * @param accountNumber - the depot account number to fetch the portfolio for, must be an account available in the config.bankingInformation.UPD.accounts
94
+ * @param account - the depot account number to fetch the portfolio for, must be an account available in the config.bankingInformation.UPD.accounts
93
95
  * @param currency - optional currency filter for the portfolio statement
94
96
  * @param priceQuality - optional price quality filter ('1' for real-time, '2' for delayed)
95
97
  * @param maxEntries - optional maximum number of entries to retrieve
96
98
  * @returns a portfolio response containing holdings and total value
97
99
  */
98
- getPortfolio(accountNumber: string, currency?: string, priceQuality?: '1' | '2', maxEntries?: number): Promise<PortfolioResponse>;
100
+ getPortfolio(account: AccountRef, currency?: string, priceQuality?: '1' | '2', maxEntries?: number): Promise<PortfolioResponse>;
99
101
  /**
100
102
  * Continues the portfolio fetching when a TAN is required
101
103
  * @param tanReference The TAN reference provided in the first call's response
@@ -106,19 +108,19 @@ export declare class FinTSClient {
106
108
  getPortfolioWithTan(tanReference: string, tan?: string): Promise<PortfolioResponse>;
107
109
  /**
108
110
  * Checks if the bank supports fetching credit card statements in general or for the given account number
109
- * @param accountNumber when the account number is provided, checks if the account supports fetching of statements
111
+ * @param account when the account number is provided, checks if the account supports fetching of statements
110
112
  * @returns true if the bank (and account) supports fetching credit card statements
111
113
  */
112
- canGetCreditCardStatements(accountNumber?: string): boolean;
114
+ canGetCreditCardStatements(account?: AccountRef): boolean;
113
115
  /**
114
116
  * Fetches the credit card statements for the given account number
115
- * @param accountNumber - the account number to fetch the statements for, must be a credit card account available
117
+ * @param account - the account number to fetch the statements for, must be a credit card account available
116
118
  * in the config.baningInformation.UPD.accounts
117
119
  * @param from - an optional start date of the period to fetch the statements for
118
120
  * @param to - an optional end date of the period to fetch the statements for
119
121
  * @returns an account statements response containing an array of statements
120
122
  */
121
- getCreditCardStatements(accountNumber: string, from?: Date): Promise<StatementResponse>;
123
+ getCreditCardStatements(account: AccountRef, from?: Date): Promise<StatementResponse>;
122
124
  /**
123
125
  * Continues the credit card statements fetching when a TAN is required
124
126
  * @param tanReference The TAN reference provided in the first call's response
@@ -126,6 +128,33 @@ export declare class FinTSClient {
126
128
  * @returns a credit card statements response containing an array of statements
127
129
  */
128
130
  getCreditCardStatementsWithTan(tanReference: string, tan?: string): Promise<StatementResponse>;
131
+ /**
132
+ * Checks if the bank supports fetching electronic account statements in general or for the given account number
133
+ * @param account when the account number is provided, checks if the account supports fetching of electronic statements
134
+ * @returns true if the bank (and account) supports fetching electronic account statements
135
+ */
136
+ canGetElectronicStatements(account?: AccountRef): boolean;
137
+ /**
138
+ * Fetches an electronic account statement (Elektronischer Kontoauszug) for the given account number
139
+ *
140
+ * This returns the statement document the bank files in the customer's electronic mailbox,
141
+ * usually a PDF, not a list of transactions. The bank hands out one statement per call and
142
+ * announces a waiting successor in `nextOffset`; pass that value back in `options.offset` to
143
+ * fetch the next one. Banks that set `receiptRequired` in their HIEKAS parameters keep
144
+ * offering a statement until it has been acknowledged with its receipt.
145
+ *
146
+ * @param account - the account number to fetch the statement for, must be an account available in the config.bankingInformation.upd.accounts
147
+ * @param options - optional format, statement number and year, entry limit and offset
148
+ * @returns a response containing the statement documents and the offset of a waiting successor
149
+ */
150
+ getElectronicStatements(account: AccountRef, options?: ElectronicStatementOptions): Promise<ElectronicStatementResponse>;
151
+ /**
152
+ * Continues the electronic account statement fetching when a TAN is required
153
+ * @param tanReference The TAN reference provided in the first call's response
154
+ * @param tan The TAN entered by the user, can be omitted if a decoupled TAN method is used
155
+ * @returns a response containing the statement documents
156
+ */
157
+ getElectronicStatementsWithTan(tanReference: string, tan?: string): Promise<ElectronicStatementResponse>;
129
158
  private startCustomerOrderInteraction;
130
159
  private continueCustomerInteractionWithTan;
131
160
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACN,KAAK,sBAAsB,EAE3B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,KAAK,EAGX,iBAAiB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAEN,KAAK,iBAAiB,EACtB,MAAM,wCAAwC,CAAC;AAShD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,mBAAoB,SAAQ,YAAY;CAAG;AAE5D;;GAEG;AACH,qBAAa,WAAW;IAOJ,MAAM,EAAE,WAAW;IANtC,OAAO,CAAC,aAAa,CAAqB;IAE1C;;;OAGG;gBACgB,MAAM,EAAE,WAAW;IAUtC;;;;OAIG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS;IAI/C;;;OAGG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAMjD;;;;;OAKG;IACG,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAI1F;;;;OAIG;IACH,oBAAoB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO;IAMrD;;;;OAIG;IACG,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAO/E;;;;;OAKG;IACG,wBAAwB,CAC7B,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GACV,OAAO,CAAC,sBAAsB,CAAC;IAQlC;;;;OAIG;IACH,uBAAuB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO;IAexD;;;;;;;OAOG;IACG,oBAAoB,CACzB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,IAAI,EACX,EAAE,CAAC,EAAE,IAAI,EACT,UAAU,GAAE,OAAc,GACxB,OAAO,CAAC,iBAAiB,CAAC;IAuB7B;;;;;OAKG;IACG,2BAA2B,CAChC,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC;IAQ7B;;;;OAIG;IACH,eAAe,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO;IAMhD;;;;;;;OAOG;IACG,YAAY,CACjB,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,EACxB,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC;IAM7B;;;;;;OAMG;IACG,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQzF;;;;OAIG;IACH,0BAA0B,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO;IAM3D;;;;;;;OAOG;IACG,uBAAuB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAM7F;;;;;OAKG;IACG,8BAA8B,CACnC,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC;YAQf,6BAA6B;YAsB7B,kCAAkC;CA2BhD"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { BankAccount } from './bankAccount.js';
1
+ import type { AccountRef, BankAccount } from './bankAccount.js';
2
2
  import type { BankingInformation } from './bankingInformation.js';
3
3
  import type { TanMethod } from './tanMethod.js';
4
4
  /**
@@ -86,21 +86,42 @@ export declare class FinTSConfig {
86
86
  * @param transId The transaction ID
87
87
  */
88
88
  isTransactionSupported(transId: string): boolean;
89
+ /**
90
+ * The account the bank meant, without demanding that it be unambiguous.
91
+ *
92
+ * For entries the *bank* supplied — a SEPA account from HISPA, say — rather than
93
+ * ones a caller asked for. A caller who names an ambiguous account has made a
94
+ * mistake worth an exception; a bank listing its own accounts has not, and
95
+ * throwing there would break every dialog at an institution that shares numbers.
96
+ *
97
+ * @param account An account number with, where the bank gave one, its sub-account id
98
+ */
99
+ matchBankAccount(account: {
100
+ accountNumber: string;
101
+ subAccountId?: string;
102
+ }): BankAccount | undefined;
89
103
  /**
90
104
  * Checks if a transaction is supported for a specific account
91
- * @param accountNumber The account number
105
+ * @param account An account number, or an account from `bankingInformation.upd.bankAccounts`
92
106
  * @param transId The transaction ID
93
107
  */
94
- isAccountTransactionSupported(accountNumber: string, transId: string): boolean;
108
+ isAccountTransactionSupported(account: AccountRef, transId: string): boolean;
95
109
  /**
96
110
  * Gets the maximum supported transaction version of a transaction, considering this client's support and the bank's support
97
111
  * @param transId The transaction ID
98
112
  */
99
113
  getMaxSupportedTransactionVersion(transId: string): number | undefined;
100
114
  /**
101
- * Gets the bank account information for a specific account number
102
- * @param accountNumber The account number
115
+ * Resolves an account reference against the accounts the bank reported.
116
+ *
117
+ * A number alone is enough wherever it is unique, which is the usual case. Where
118
+ * it is not, this throws instead of picking one: FinTS identifies an account by
119
+ * number *and* sub-account id, so a number that matches two accounts does not say
120
+ * which one is meant, and answering for the wrong one produces a balance or a list
121
+ * of transactions that belongs to a different account with nothing to indicate it.
122
+ *
123
+ * @param account An account number, or an account from `bankingInformation.upd.bankAccounts`
103
124
  */
104
- getBankAccount(accountNumber: string): BankAccount;
125
+ getBankAccount(account: AccountRef): BankAccount;
105
126
  }
106
127
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;GAEG;AACH,qBAAa,WAAW;IAKf,SAAS,EAAE,MAAM;IACjB,cAAc,EAAE,MAAM;IAC7B,OAAO,CAAC,GAAG,CAAC;IACZ,OAAO,CAAC,kBAAkB,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM;IACf,GAAG,CAAC,EAAE,MAAM;IAEZ,WAAW,CAAC,EAAE,MAAM;IACpB,YAAY,CAAC,EAAE,MAAM;IACrB,UAAU,CAAC,EAAE,MAAM;IAC1B,OAAO,CAAC,OAAO;IAdhB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,YAAY,UAAS;IAErB,OAAO;IA+CP;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,eAAe,CACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,MAAY,GACvB,WAAW;IAgBd;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,sBAAsB,CAC5B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,kBAAkB,EACtC,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,MAAY,GACvB,WAAW;IAgBd;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,mBAAmB,IAAI,SAAS,EAAE,CAMrC;IAED;;;OAGG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS;IAU/C;;;OAGG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM;IAcnC;;OAEG;IACH,IAAI,iBAAiB,IAAI,SAAS,GAAG,SAAS,CAE7C;IAED;;;;OAIG;IACH,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAO3D;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOhD;;;;OAIG;IACH,6BAA6B,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAK9E;;;OAGG;IACH,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAgBtE;;;OAGG;IACH,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW;CAWlD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;GAEG;AACH,qBAAa,WAAW;IAKf,SAAS,EAAE,MAAM;IACjB,cAAc,EAAE,MAAM;IAC7B,OAAO,CAAC,GAAG,CAAC;IACZ,OAAO,CAAC,kBAAkB,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM;IACf,GAAG,CAAC,EAAE,MAAM;IAEZ,WAAW,CAAC,EAAE,MAAM;IACpB,YAAY,CAAC,EAAE,MAAM;IACrB,UAAU,CAAC,EAAE,MAAM;IAC1B,OAAO,CAAC,OAAO;IAdhB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,YAAY,UAAS;IAErB,OAAO;IA+CP;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,eAAe,CACrB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,MAAY,GACvB,WAAW;IAgBd;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,sBAAsB,CAC5B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,kBAAkB,EACtC,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,MAAY,GACvB,WAAW;IAgBd;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,mBAAmB,IAAI,SAAS,EAAE,CAMrC;IAED;;;OAGG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS;IAU/C;;;OAGG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM;IAcnC;;OAEG;IACH,IAAI,iBAAiB,IAAI,SAAS,GAAG,SAAS,CAE7C;IAED;;;;OAIG;IACH,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAO3D;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOhD;;;;;;;;;OASG;IACH,gBAAgB,CAAC,OAAO,EAAE;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,WAAW,GAAG,SAAS;IAiB3B;;;;OAIG;IACH,6BAA6B,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAK5E;;;OAGG;IACH,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAgBtE;;;;;;;;;;OAUG;IACH,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,WAAW;CAqChD"}
@@ -3,6 +3,13 @@ export declare class Binary extends DataElement {
3
3
  maxLength?: number | undefined;
4
4
  constructor(name: string, minCount?: number, maxCount?: number, maxLength?: number | undefined, minVersion?: number, maxVersion?: number);
5
5
  encode(value: string): string;
6
+ /**
7
+ * A binary value arrives as `@<length>@<data>`. The length is authoritative: it is the
8
+ * only thing that tells data apart from the separators and escape characters that a
9
+ * binary payload — a PDF, for instance — is full of. Returning everything after the
10
+ * second `@` instead would hand out whatever the bank appended between the end of the
11
+ * data and the next separator.
12
+ */
6
13
  decode(text: string): string;
7
14
  }
8
15
  //# sourceMappingURL=Binary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Binary.d.ts","sourceRoot":"","sources":["../../../src/dataElements/Binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,qBAAa,MAAO,SAAQ,WAAW;IAK9B,SAAS,CAAC,EAAE,MAAM;gBAHzB,IAAI,EAAE,MAAM,EACZ,QAAQ,SAAI,EACZ,QAAQ,SAAI,EACL,SAAS,CAAC,EAAE,MAAM,YAAA,EACzB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM;IAKpB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAY7B,MAAM,CAAC,IAAI,EAAE,MAAM;CAGnB"}
1
+ {"version":3,"file":"Binary.d.ts","sourceRoot":"","sources":["../../../src/dataElements/Binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,qBAAa,MAAO,SAAQ,WAAW;IAK9B,SAAS,CAAC,EAAE,MAAM;gBAHzB,IAAI,EAAE,MAAM,EACZ,QAAQ,SAAI,EACZ,QAAQ,SAAI,EACL,SAAS,CAAC,EAAE,MAAM,YAAA,EACzB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM;IAKpB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAY7B;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM;CAgBnB"}
@@ -19,6 +19,20 @@ export declare class Dialog {
19
19
  private createCurrentCustomerMessage;
20
20
  private createCurrentTanMessage;
21
21
  private getTanMediaName;
22
+ /**
23
+ * Collects a response that the bank spreads over several messages.
24
+ *
25
+ * When the bank cannot fit a response into one message it answers with code 3040 plus
26
+ * a continuation mark. Repeating the order with that mark yields the next portion —
27
+ * as a COMPLETE, self-contained response segment, not as a byte-wise continuation of
28
+ * the previous one. A HICAZ follow-up, for example, repeats the account and the CAMT
29
+ * descriptor before carrying its own share of the statements.
30
+ *
31
+ * Every portion is therefore decoded on its own and all of them are placed into the
32
+ * response message the caller holds. Combining their payloads needs to know what the
33
+ * payload means — one MT940 stream continues, a list of CAMT documents is appended —
34
+ * so that step belongs to the interaction, which does it via `findAllSegments`.
35
+ */
22
36
  private handlePartedMessages;
23
37
  private checkEnded;
24
38
  private getHttpClient;
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/dialog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EAExB,MAAM,uCAAuC,CAAC;AAW/C,qBAAa,MAAM;IAWV,MAAM,EAAE,WAAW;IAV3B,QAAQ,EAAE,MAAM,CAAO;IACvB,iBAAiB,SAAK;IACtB,YAAY,EAAE,mBAAmB,EAAE,CAAM;IACzC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAa;IACnD,uBAAuB,SAAK;IAC5B,aAAa,UAAS;IACtB,QAAQ,UAAS;IACjB,UAAU,EAAE,UAAU,CAAC;gBAGf,MAAM,EAAE,WAAW,EAC1B,YAAY,GAAE,OAAe;IAc9B,IAAI,kBAAkB,IAAI,mBAAmB,CAE5C;IAEK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAyC7C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAmD7F,sBAAsB,CAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,UAAQ,GAAG,IAAI;IAuBpF,OAAO,CAAC,4BAA4B;IAuDpC,OAAO,CAAC,uBAAuB;IAiC/B,OAAO,CAAC,eAAe;YAeT,oBAAoB;IAoDlC,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,aAAa;CAGrB"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/dialog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,mBAAmB,EAExB,MAAM,uCAAuC,CAAC;AAW/C,qBAAa,MAAM;IAWV,MAAM,EAAE,WAAW;IAV3B,QAAQ,EAAE,MAAM,CAAO;IACvB,iBAAiB,SAAK;IACtB,YAAY,EAAE,mBAAmB,EAAE,CAAM;IACzC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAa;IACnD,uBAAuB,SAAK;IAC5B,aAAa,UAAS;IACtB,QAAQ,UAAS;IACjB,UAAU,EAAE,UAAU,CAAC;gBAGf,MAAM,EAAE,WAAW,EAC1B,YAAY,GAAE,OAAe;IAc9B,IAAI,kBAAkB,IAAI,mBAAmB,CAE5C;IAEK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAyC7C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAmD7F,sBAAsB,CAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,UAAQ,GAAG,IAAI;IAuBpF,OAAO,CAAC,4BAA4B;IAuDpC,OAAO,CAAC,uBAAuB;IAiC/B,OAAO,CAAC,eAAe;IAevB;;;;;;;;;;;;;OAaG;YACW,oBAAoB;IA8DlC,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,aAAa;CAGrB"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * An electronic account statement (Elektronischer Kontoauszug) as handed out by the bank.
3
+ *
4
+ * Unlike {@link Statement} this is not a list of parsed transactions but the statement
5
+ * document itself — the same document the bank files in the customer's electronic mailbox,
6
+ * usually a PDF.
7
+ */
8
+ export type ElectronicStatement = {
9
+ /** The format of {@link document}, as announced by the bank in the HIEKAS parameters */
10
+ format: string;
11
+ /** Start of the period the statement covers */
12
+ from?: Date;
13
+ /** End of the period the statement covers */
14
+ to?: Date;
15
+ /** The date the statement was created by the bank */
16
+ date?: Date;
17
+ /** The year the statement number refers to, statement numbers restart every year */
18
+ year?: number;
19
+ /** The sequential number of the statement within its year */
20
+ number?: number;
21
+ /** The statement document itself */
22
+ document: Uint8Array;
23
+ /** Information about the closing of the accounting period, when the bank provides it */
24
+ closingInfo?: string;
25
+ /** Information about the conditions of the account, when the bank provides it */
26
+ conditionsInfo?: string;
27
+ /** Advertising text, when the bank provides it */
28
+ advertisement?: string;
29
+ iban?: string;
30
+ bic?: string;
31
+ /** The account holder's name, joined from the up to three name lines the bank sends */
32
+ accountName?: string;
33
+ /**
34
+ * The receipt for this statement. When the bank requires acknowledgement
35
+ * (`receiptRequired` in the HIEKAS parameters), it only stops handing out a statement
36
+ * once it has been acknowledged with this receipt.
37
+ */
38
+ receipt?: string;
39
+ };
40
+ //# sourceMappingURL=electronicStatement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"electronicStatement.d.ts","sourceRoot":"","sources":["../../src/electronicStatement.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAC;IAEf,+CAA+C;IAC/C,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ,6CAA6C;IAC7C,EAAE,CAAC,EAAE,IAAI,CAAC;IAEV,qDAAqD;IACrD,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,oCAAoC;IACpC,QAAQ,EAAE,UAAU,CAAC;IAErB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
@@ -6,14 +6,17 @@ export * from './bpd.js';
6
6
  export * from './client.js';
7
7
  export * from './config.js';
8
8
  export * from './dialog.js';
9
+ export * from './electronicStatement.js';
9
10
  export * from './httpClient.js';
10
11
  export { AccountBalanceResponse } from './interactions/balanceInteraction.js';
11
12
  export { ClientResponse, StatementResponse } from './interactions/customerInteraction.js';
13
+ export { ElectronicStatementOptions, ElectronicStatementResponse, } from './interactions/electronicStatementInteraction.js';
12
14
  export { PortfolioResponse } from './interactions/portfolioInteraction.js';
13
15
  export * from './message.js';
14
16
  export * from './mt535parser.js';
15
17
  export * from './mt940parser.js';
16
18
  export * from './segment.js';
19
+ export { StatementFormat } from './segments/HKEKA.js';
17
20
  export * from './statement.js';
18
21
  export * from './upd.js';
19
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EACN,0BAA0B,EAC1B,2BAA2B,GAC3B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { AccountBalance } from '../accountBalance.js';
2
+ import { type AccountRef } from '../bankAccount.js';
2
3
  import type { FinTSConfig } from '../config.js';
3
4
  import type { Message } from '../message.js';
4
5
  import type { Segment } from '../segment.js';
@@ -7,8 +8,8 @@ export interface AccountBalanceResponse extends ClientResponse {
7
8
  balance?: AccountBalance;
8
9
  }
9
10
  export declare class BalanceInteraction extends CustomerOrderInteraction {
10
- accountNumber: string;
11
- constructor(accountNumber: string);
11
+ account: AccountRef;
12
+ constructor(account: AccountRef);
12
13
  createSegments(init: FinTSConfig): Segment[];
13
14
  handleResponse(response: Message, clientResponse: AccountBalanceResponse): void;
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"balanceInteraction.d.ts","sourceRoot":"","sources":["../../../src/interactions/balanceInteraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,KAAK,cAAc,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC7D,OAAO,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,qBAAa,kBAAmB,SAAQ,wBAAwB;IAC5C,aAAa,EAAE,MAAM;gBAArB,aAAa,EAAE,MAAM;IAIxC,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,EAAE;IA0B5C,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,sBAAsB;CAaxE"}
1
+ {"version":3,"file":"balanceInteraction.d.ts","sourceRoot":"","sources":["../../../src/interactions/balanceInteraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAErE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,KAAK,cAAc,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC7D,OAAO,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,qBAAa,kBAAmB,SAAQ,wBAAwB;IAC5C,OAAO,EAAE,UAAU;gBAAnB,OAAO,EAAE,UAAU;IAItC,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,EAAE;IA0B5C,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,sBAAsB;CAaxE"}