lib-fints 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +4 -0
  2. package/dist/client.js +33 -0
  3. package/dist/index.js +1 -0
  4. package/dist/interactions/portfolioInteraction.js +57 -0
  5. package/dist/mt535parser.js +196 -0
  6. package/dist/partedSegment.js +4 -1
  7. package/dist/segment.js +3 -5
  8. package/dist/segmentDefinition.js +4 -1
  9. package/dist/segments/HIBPA.js +4 -1
  10. package/dist/segments/HIKAZ.js +4 -1
  11. package/dist/segments/HIKAZS.js +2 -2
  12. package/dist/segments/HIKIM.js +4 -1
  13. package/dist/segments/HIKOM.js +4 -1
  14. package/dist/segments/HIPINS.js +2 -2
  15. package/dist/segments/HIRMG.js +4 -1
  16. package/dist/segments/HIRMS.js +4 -1
  17. package/dist/segments/HISAL.js +4 -1
  18. package/dist/segments/HISYN.js +4 -1
  19. package/dist/segments/HITAB.js +4 -1
  20. package/dist/segments/HITAN.js +4 -1
  21. package/dist/segments/HITANS.js +2 -2
  22. package/dist/segments/HIUPA.js +4 -1
  23. package/dist/segments/HIUPD.js +4 -1
  24. package/dist/segments/HIWPD.js +15 -0
  25. package/dist/segments/HKEND.js +4 -1
  26. package/dist/segments/HKIDN.js +4 -1
  27. package/dist/segments/HKKAZ.js +4 -1
  28. package/dist/segments/HKSAL.js +4 -1
  29. package/dist/segments/HKSYN.js +4 -1
  30. package/dist/segments/HKTAB.js +4 -1
  31. package/dist/segments/HKTAN.js +4 -1
  32. package/dist/segments/HKVVB.js +4 -1
  33. package/dist/segments/HKWPD.js +23 -0
  34. package/dist/segments/HNHBK.js +4 -1
  35. package/dist/segments/HNHBS.js +4 -1
  36. package/dist/segments/HNSHA.js +4 -1
  37. package/dist/segments/HNSHK.js +4 -1
  38. package/dist/segments/HNVSD.js +5 -2
  39. package/dist/segments/HNVSK.js +5 -2
  40. package/dist/segments/businessTransactionParameter.js +2 -2
  41. package/dist/segments/registry.js +4 -0
  42. package/dist/tests/HIWPD.test.js +25 -0
  43. package/dist/tests/HKWPD.test.js +38 -0
  44. package/dist/tests/mt535parser.test.js +157 -0
  45. package/dist/types/client.d.ts +24 -0
  46. package/dist/types/client.d.ts.map +1 -1
  47. package/dist/types/index.d.ts +2 -0
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/types/interactions/portfolioInteraction.d.ts +39 -0
  50. package/dist/types/interactions/portfolioInteraction.d.ts.map +1 -0
  51. package/dist/types/mt535parser.d.ts +44 -0
  52. package/dist/types/mt535parser.d.ts.map +1 -0
  53. package/dist/types/partedSegment.d.ts +1 -0
  54. package/dist/types/partedSegment.d.ts.map +1 -1
  55. package/dist/types/segment.d.ts.map +1 -1
  56. package/dist/types/segmentDefinition.d.ts +1 -0
  57. package/dist/types/segmentDefinition.d.ts.map +1 -1
  58. package/dist/types/segments/HIBPA.d.ts +1 -0
  59. package/dist/types/segments/HIBPA.d.ts.map +1 -1
  60. package/dist/types/segments/HIKAZ.d.ts +1 -0
  61. package/dist/types/segments/HIKAZ.d.ts.map +1 -1
  62. package/dist/types/segments/HIKAZS.d.ts.map +1 -1
  63. package/dist/types/segments/HIKIM.d.ts +1 -0
  64. package/dist/types/segments/HIKIM.d.ts.map +1 -1
  65. package/dist/types/segments/HIKOM.d.ts +1 -0
  66. package/dist/types/segments/HIKOM.d.ts.map +1 -1
  67. package/dist/types/segments/HIPINS.d.ts.map +1 -1
  68. package/dist/types/segments/HIRMG.d.ts +1 -0
  69. package/dist/types/segments/HIRMG.d.ts.map +1 -1
  70. package/dist/types/segments/HIRMS.d.ts +1 -0
  71. package/dist/types/segments/HIRMS.d.ts.map +1 -1
  72. package/dist/types/segments/HISAL.d.ts +1 -0
  73. package/dist/types/segments/HISAL.d.ts.map +1 -1
  74. package/dist/types/segments/HISYN.d.ts +1 -0
  75. package/dist/types/segments/HISYN.d.ts.map +1 -1
  76. package/dist/types/segments/HITAB.d.ts +1 -0
  77. package/dist/types/segments/HITAB.d.ts.map +1 -1
  78. package/dist/types/segments/HITAN.d.ts +1 -0
  79. package/dist/types/segments/HITAN.d.ts.map +1 -1
  80. package/dist/types/segments/HITANS.d.ts.map +1 -1
  81. package/dist/types/segments/HIUPA.d.ts +1 -0
  82. package/dist/types/segments/HIUPA.d.ts.map +1 -1
  83. package/dist/types/segments/HIUPD.d.ts +1 -0
  84. package/dist/types/segments/HIUPD.d.ts.map +1 -1
  85. package/dist/types/segments/HIWPD.d.ts +22 -0
  86. package/dist/types/segments/HIWPD.d.ts.map +1 -0
  87. package/dist/types/segments/HKEND.d.ts +1 -0
  88. package/dist/types/segments/HKEND.d.ts.map +1 -1
  89. package/dist/types/segments/HKIDN.d.ts +1 -0
  90. package/dist/types/segments/HKIDN.d.ts.map +1 -1
  91. package/dist/types/segments/HKKAZ.d.ts +1 -0
  92. package/dist/types/segments/HKKAZ.d.ts.map +1 -1
  93. package/dist/types/segments/HKSAL.d.ts +1 -0
  94. package/dist/types/segments/HKSAL.d.ts.map +1 -1
  95. package/dist/types/segments/HKSYN.d.ts +1 -0
  96. package/dist/types/segments/HKSYN.d.ts.map +1 -1
  97. package/dist/types/segments/HKTAB.d.ts +1 -0
  98. package/dist/types/segments/HKTAB.d.ts.map +1 -1
  99. package/dist/types/segments/HKTAN.d.ts +1 -0
  100. package/dist/types/segments/HKTAN.d.ts.map +1 -1
  101. package/dist/types/segments/HKVVB.d.ts +1 -0
  102. package/dist/types/segments/HKVVB.d.ts.map +1 -1
  103. package/dist/types/segments/HKWPD.d.ts +43 -0
  104. package/dist/types/segments/HKWPD.d.ts.map +1 -0
  105. package/dist/types/segments/HNHBK.d.ts +1 -0
  106. package/dist/types/segments/HNHBK.d.ts.map +1 -1
  107. package/dist/types/segments/HNHBS.d.ts +1 -0
  108. package/dist/types/segments/HNHBS.d.ts.map +1 -1
  109. package/dist/types/segments/HNSHA.d.ts +1 -0
  110. package/dist/types/segments/HNSHA.d.ts.map +1 -1
  111. package/dist/types/segments/HNSHK.d.ts +1 -0
  112. package/dist/types/segments/HNSHK.d.ts.map +1 -1
  113. package/dist/types/segments/HNVSD.d.ts +1 -0
  114. package/dist/types/segments/HNVSD.d.ts.map +1 -1
  115. package/dist/types/segments/HNVSK.d.ts +1 -0
  116. package/dist/types/segments/HNVSK.d.ts.map +1 -1
  117. package/dist/types/segments/businessTransactionParameter.d.ts +1 -1
  118. package/dist/types/segments/businessTransactionParameter.d.ts.map +1 -1
  119. package/dist/types/segments/registry.d.ts.map +1 -1
  120. package/dist/types/tests/HIWPD.test.d.ts +2 -0
  121. package/dist/types/tests/HIWPD.test.d.ts.map +1 -0
  122. package/dist/types/tests/HKWPD.test.d.ts +2 -0
  123. package/dist/types/tests/HKWPD.test.d.ts.map +1 -0
  124. package/dist/types/tests/mt535parser.test.d.ts +2 -0
  125. package/dist/types/tests/mt535parser.test.d.ts.map +1 -0
  126. package/dist/types/unknownSegment.d.ts +1 -0
  127. package/dist/types/unknownSegment.d.ts.map +1 -1
  128. package/dist/unknownSegment.js +4 -1
  129. package/package.json +1 -1
package/README.md CHANGED
@@ -86,6 +86,9 @@ const balanceResponse = await client.getAccountBalance(account.accountNumber);
86
86
 
87
87
  // fetch all available statements
88
88
  const statementResponse = await client.getAccountStatements(account.accountNumber);
89
+
90
+ // or fetch portfolio from a securities account
91
+ client.getPortfolio(account.accountNumber);
89
92
  ```
90
93
 
91
94
  These are only the most basic steps needed to retrieve information from the bank. There are still some unanswered questions like "how to handle TANs" or "how to avoid synchronizations every time you start a new session". These are explained in the corresponding sections below.
@@ -191,6 +194,7 @@ This will print out all sent messages and received responses to the console in a
191
194
  - Synchronize bank and account information
192
195
  - Fetching account balances
193
196
  - Fetching account statements
197
+ - Fetching the portfolio of a securities account
194
198
 
195
199
  Implementing further transactions should be straight forward and contributions are highly appreciated
196
200
 
package/dist/client.js CHANGED
@@ -2,10 +2,12 @@ import { Dialog } from './dialog.js';
2
2
  import { HKTAB } from './segments/HKTAB.js';
3
3
  import { StatementInteraction } from './interactions/statementInteraction.js';
4
4
  import { BalanceInteraction } from './interactions/balanceInteraction.js';
5
+ import { PortfolioInteraction } from './interactions/portfolioInteraction.js';
5
6
  import { FinTSConfig } from './config.js';
6
7
  import { TanMediaInteraction } from './interactions/tanMediaInteraction.js';
7
8
  import { HKSAL } from './segments/HKSAL.js';
8
9
  import { HKKAZ } from './segments/HKKAZ.js';
10
+ import { HKWPD } from './segments/HKWPD.js';
9
11
  import { InitDialogInteraction } from './interactions/initDialogInteraction.js';
10
12
  /**
11
13
  * A client to communicate with a bank over the FinTS protocol
@@ -128,6 +130,37 @@ export class FinTSClient {
128
130
  async getAccountStatementsWithTan(tanReference, tan) {
129
131
  return this.continueCustomerInteractionWithTan(tanReference, tan);
130
132
  }
133
+ /**
134
+ * Checks if the bank supports fetching portfolio information in general or for the given account number when provided
135
+ * @param accountNumber when the account number is provided, checks if the account supports fetching of portfolio information
136
+ * @returns true if the bank (and account) supports fetching portfolio information
137
+ */
138
+ canGetPortfolio(accountNumber) {
139
+ return accountNumber
140
+ ? this.config.isAccountTransactionSupported(accountNumber, HKWPD.Id)
141
+ : this.config.isTransactionSupported(HKWPD.Id);
142
+ }
143
+ /**
144
+ * Fetches the portfolio information for the given depot account number
145
+ * @param accountNumber - the depot account number to fetch the portfolio for, must be an account available in the config.bankingInformation.UPD.accounts
146
+ * @param currency - optional currency filter for the portfolio statement
147
+ * @param priceQuality - optional price quality filter ('1' for real-time, '2' for delayed)
148
+ * @param maxEntries - optional maximum number of entries to retrieve
149
+ * @returns a portfolio response containing holdings and total value
150
+ */
151
+ async getPortfolio(accountNumber, currency, priceQuality, maxEntries) {
152
+ return this.startCustomerOrderInteraction(new PortfolioInteraction(accountNumber, currency, priceQuality, maxEntries));
153
+ }
154
+ /**
155
+ * Continues the portfolio fetching when a TAN is required
156
+ * @param tanReference The TAN reference provided in the first call's response
157
+
158
+ * @param tan The TAN entered by the user, can be omitted if a decoupled TAN method is used
159
+ * @returns a portfolio response containing holdings and total value
160
+ */
161
+ async getPortfolioWithTan(tanReference, tan) {
162
+ return this.continueCustomerInteractionWithTan(tanReference, tan);
163
+ }
131
164
  async startCustomerOrderInteraction(interaction) {
132
165
  const dialog = new Dialog(this.config);
133
166
  const syncResponse = await this.initDialog(dialog, false, interaction);
package/dist/index.js CHANGED
@@ -13,3 +13,4 @@ export * from './accountBalance.js';
13
13
  export * from './bpd.js';
14
14
  export * from './upd.js';
15
15
  export * from './mt940parser.js';
16
+ export * from './mt535parser.js';
@@ -0,0 +1,57 @@
1
+ import { CustomerOrderInteraction, } from './customerInteraction.js';
2
+ import { HKWPD } from '../segments/HKWPD.js';
3
+ import { HIWPD } from '../segments/HIWPD.js';
4
+ import { Mt535Parser } from '../mt535parser.js';
5
+ /**
6
+ * Interaction for requesting and parsing stock portfolio information (HKWPD/HIWPD)
7
+ */
8
+ export class PortfolioInteraction extends CustomerOrderInteraction {
9
+ accountNumber;
10
+ currency;
11
+ priceQuality;
12
+ maxEntries;
13
+ paginationMarker;
14
+ constructor(accountNumber, currency, priceQuality, maxEntries, paginationMarker) {
15
+ super(HKWPD.Id, HIWPD.Id);
16
+ this.accountNumber = accountNumber;
17
+ this.currency = currency;
18
+ this.priceQuality = priceQuality;
19
+ this.maxEntries = maxEntries;
20
+ this.paginationMarker = paginationMarker;
21
+ }
22
+ createSegments(config) {
23
+ const bankAccount = config.getBankAccount(this.accountNumber);
24
+ if (!config.isAccountTransactionSupported(this.accountNumber, this.segId)) {
25
+ throw Error(`Account ${this.accountNumber} does not support business transaction '${this.segId}'`);
26
+ }
27
+ const depotAccount = { ...bankAccount, iban: undefined }; // HKWPD uses KTV which doesn't have IBAN
28
+ const version = config.getMaxSupportedTransactionVersion(HKWPD.Id);
29
+ if (!version) {
30
+ throw Error(`There is no supported version for business transaction '${HKWPD.Id}'`);
31
+ }
32
+ const hkwpd = {
33
+ header: { segId: HKWPD.Id, segNr: 0, version: version },
34
+ depot: depotAccount,
35
+ currency: this.currency,
36
+ priceQuality: this.priceQuality,
37
+ maxEntries: this.maxEntries,
38
+ paginationMarker: this.paginationMarker,
39
+ };
40
+ return [hkwpd];
41
+ }
42
+ handleResponse(response, clientResponse) {
43
+ const hiwpdSegment = response.findSegment(HIWPD.Id);
44
+ if (hiwpdSegment?.portfolioStatement) {
45
+ try {
46
+ // Parse the MT535 data
47
+ const parser = new Mt535Parser(hiwpdSegment.portfolioStatement);
48
+ clientResponse.portfolioStatement = parser.parse();
49
+ }
50
+ catch (error) {
51
+ console.warn('Failed to parse MT535 portfolio statement:', error);
52
+ // Fallback: provide raw data if parsing fails
53
+ clientResponse.rawMT535Data = hiwpdSegment.portfolioStatement;
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,196 @@
1
+ export var TokenType535;
2
+ (function (TokenType535) {
3
+ TokenType535["DepotValueBlock"] = "DepotValueBlock";
4
+ TokenType535["DepotValueCurrency"] = "DepotValueCurrency";
5
+ TokenType535["FinBlock"] = "FinBlock";
6
+ TokenType535["SecurityIdentification"] = "SecurityIdentification";
7
+ TokenType535["AcquisitionPrice"] = "AcquisitionPrice";
8
+ TokenType535["PriceBlock"] = "PriceBlock";
9
+ TokenType535["AmountBlock"] = "AmountBlock";
10
+ TokenType535["DateTimeBlock"] = "DateTimeBlock";
11
+ TokenType535["DateString"] = "DateString";
12
+ TokenType535["TimeString"] = "TimeString";
13
+ })(TokenType535 || (TokenType535 = {}));
14
+ const tokens535 = {
15
+ [TokenType535.DepotValueBlock]: /:16R:ADDINFO(.*?):16S:ADDINFO/ms,
16
+ [TokenType535.DepotValueCurrency]: /EUR(.*)/ms,
17
+ [TokenType535.FinBlock]: /:16R:FIN(.*?):16S:FIN/gms,
18
+ [TokenType535.SecurityIdentification]: /:35B:(.*?):/ms,
19
+ [TokenType535.AcquisitionPrice]: /:70E::HOLD\/\/\d*STK2(\d*),(\d*)\+([A-Z]{3})/ms,
20
+ [TokenType535.PriceBlock]: /:90([AB])::(.*?):/ms,
21
+ [TokenType535.AmountBlock]: /:93B::(.*?):/ms,
22
+ [TokenType535.DateTimeBlock]: /:98([AC])::(.*?):/ms,
23
+ [TokenType535.DateString]: /(\d{4})(\d{2})(\d{2})/,
24
+ [TokenType535.TimeString]: /^.{14}(\d{2})(\d{2})(\d{2})/ms,
25
+ };
26
+ export class Mt535Parser {
27
+ rawData;
28
+ cleanedRawData;
29
+ constructor(rawData) {
30
+ this.rawData = rawData;
31
+ // The divider can be either \r\n or @@
32
+ const crlfCount = (rawData.match(/\r\n-/g) || []).length;
33
+ const atAtCount = (rawData.match(/@@-/g) || []).length;
34
+ const divider = crlfCount > atAtCount ? '\r\n' : '@@';
35
+ // Remove dividers that are not followed by a colon (tag indicator)
36
+ const regex = new RegExp(divider + '([^:])', 'gms');
37
+ this.cleanedRawData = rawData.replace(regex, '$1');
38
+ }
39
+ parse() {
40
+ const result = {
41
+ holdings: [],
42
+ };
43
+ // Parse total depot value
44
+ result.totalValue = this.parseDepotValue();
45
+ // Parse individual holdings
46
+ result.holdings = this.parseHoldings();
47
+ return result;
48
+ }
49
+ parseDepotValue() {
50
+ const addInfoMatch = this.cleanedRawData.match(tokens535[TokenType535.DepotValueBlock]);
51
+ if (addInfoMatch) {
52
+ const eurMatch = addInfoMatch[1].match(tokens535[TokenType535.DepotValueCurrency]);
53
+ if (eurMatch) {
54
+ return parseFloat(eurMatch[1].replace(',', '.'));
55
+ }
56
+ }
57
+ return undefined;
58
+ }
59
+ parseHoldings() {
60
+ const holdings = [];
61
+ const finBlocks = this.cleanedRawData.match(tokens535[TokenType535.FinBlock]);
62
+ if (!finBlocks) {
63
+ return holdings;
64
+ }
65
+ for (const block of finBlocks) {
66
+ const holding = this.parseHolding(block);
67
+ if (holding) {
68
+ holdings.push(holding);
69
+ }
70
+ }
71
+ return holdings;
72
+ }
73
+ parseHolding(block) {
74
+ const holding = {};
75
+ // Parse ISIN, WKN & Name from :35B:
76
+ // :35B:ISIN DE0005190003/DE/519000BAY.MOTOREN WERKE AG ST
77
+ this.parseSecurityIdentification(block, holding);
78
+ // Parse acquisition price from :70E::HOLD//
79
+ this.parseAcquisitionPrice(block, holding);
80
+ // Parse current price from :90B: or :90A:
81
+ this.parsePrice(block, holding);
82
+ // Parse amount from :93B:
83
+ this.parseAmount(block, holding);
84
+ // Parse date/time from :98A: or :98C:
85
+ this.parseDateTime(block, holding);
86
+ // Calculate value if we have price and amount
87
+ if (holding.amount !== undefined && holding.price !== undefined) {
88
+ // For all currencies, value is price multiplied by amount
89
+ holding.value = holding.price * holding.amount;
90
+ }
91
+ return holding;
92
+ }
93
+ parseSecurityIdentification(block, holding) {
94
+ const match = block.match(tokens535[TokenType535.SecurityIdentification]);
95
+ if (match) {
96
+ const content = match[1];
97
+ // ISIN: characters 5-16 (12 chars)
98
+ const isinMatch = content.match(/^.{5}(.{12})/ms);
99
+ if (isinMatch) {
100
+ holding.isin = isinMatch[1];
101
+ }
102
+ // WKN: characters 21-26 (6 chars)
103
+ const wknMatch = content.match(/^.{21}(.{6})/ms);
104
+ if (wknMatch) {
105
+ holding.wkn = wknMatch[1];
106
+ }
107
+ // Name: everything from character 27 onwards
108
+ const nameMatch = content.match(/^.{27}(.*)/ms);
109
+ if (nameMatch) {
110
+ holding.name = nameMatch[1].trim();
111
+ }
112
+ }
113
+ }
114
+ parseAcquisitionPrice(block, holding) {
115
+ const match = block.match(tokens535[TokenType535.AcquisitionPrice]);
116
+ if (match) {
117
+ holding.acquisitionPrice = parseFloat(`${match[1]}.${match[2]}`);
118
+ if (!holding.currency) {
119
+ holding.currency = match[3];
120
+ }
121
+ }
122
+ }
123
+ parsePrice(block, holding) {
124
+ const match = block.match(tokens535[TokenType535.PriceBlock]);
125
+ if (match) {
126
+ const type = match[1];
127
+ const content = match[2];
128
+ if (type === 'B') {
129
+ // Currency from characters 11-13 (3 chars)
130
+ const currencyMatch = content.match(/^.{11}(.{3})/ms);
131
+ if (currencyMatch) {
132
+ holding.currency = currencyMatch[1];
133
+ }
134
+ // Price from character 14 onwards
135
+ const priceMatch = content.match(/^.{14}(.*)/ms);
136
+ if (priceMatch) {
137
+ holding.price = parseFloat(priceMatch[1].replace(',', '.'));
138
+ }
139
+ }
140
+ else if (type === 'A') {
141
+ holding.currency = '%';
142
+ // Price from character 11 onwards
143
+ const priceMatch = content.match(/^.{11}(.*)/ms);
144
+ if (priceMatch) {
145
+ holding.price = parseFloat(priceMatch[1].replace(',', '.')) / 100;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ parseAmount(block, holding) {
151
+ const match = block.match(tokens535[TokenType535.AmountBlock]);
152
+ if (match) {
153
+ // Amount from character 11 onwards
154
+ const amountMatch = match[1].match(/^.{11}(.*)/ms);
155
+ if (amountMatch) {
156
+ holding.amount = parseFloat(amountMatch[1].replace(',', '.'));
157
+ }
158
+ }
159
+ }
160
+ parseDateTime(block, holding) {
161
+ const match = block.match(tokens535[TokenType535.DateTimeBlock]);
162
+ if (match) {
163
+ const type = match[1];
164
+ const content = match[2];
165
+ // Date from characters 6-13 (8 chars: YYYYMMDD)
166
+ const dateMatch = content.match(tokens535[TokenType535.DateString]);
167
+ if (dateMatch) {
168
+ const parsedDate = this.parseDate(dateMatch[0]);
169
+ if (type === 'C') {
170
+ // :98C: has a time component HHMMSS starting at character 14
171
+ const timeMatch = content.match(tokens535[TokenType535.TimeString]);
172
+ if (timeMatch) {
173
+ parsedDate.setHours(parseInt(timeMatch[1]), parseInt(timeMatch[2]), parseInt(timeMatch[3]));
174
+ }
175
+ }
176
+ else {
177
+ // :98A: time defaults to 00:00:00
178
+ parsedDate.setHours(0, 0, 0, 0);
179
+ }
180
+ holding.date = parsedDate;
181
+ }
182
+ }
183
+ }
184
+ parseDate(dateString) {
185
+ const match = dateString.match(tokens535[TokenType535.DateString]);
186
+ if (!match) {
187
+ throw new Error(`Invalid date format: ${dateString}`);
188
+ }
189
+ try {
190
+ return new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]));
191
+ }
192
+ catch (error) {
193
+ throw new Error(`Invalid date: ${dateString}`, { cause: error });
194
+ }
195
+ }
196
+ }
@@ -1,7 +1,10 @@
1
1
  import { Text } from './dataElements/Text.js';
2
2
  import { SegmentDefinition } from './segmentDefinition.js';
3
3
  export class PARTED extends SegmentDefinition {
4
- static Id = this.name;
4
+ static Id = 'PARTED';
5
+ constructor() {
6
+ super(PARTED.Id);
7
+ }
5
8
  version = 1;
6
9
  elements = [new Text('rawData', 0, 1)];
7
10
  }
package/dist/segment.js CHANGED
@@ -45,11 +45,9 @@ export function segmentToString(segment) {
45
45
  const segmentDefinition = getSegmentDefinition(segment.header.segId);
46
46
  let texts = segmentDefinition.getElementsForVersion(segment.header.version).map((element) => {
47
47
  if (element.maxCount > 1) {
48
- return (keyedSegment[element.name] ??
49
- []
50
- .map((value) => element.toString(value))
51
- .filter((text) => !!text)
52
- .join('; '));
48
+ const array = keyedSegment[element.name] ?? [];
49
+ const texts = array.map((value) => element.toString(value));
50
+ return texts.filter((text) => !!text).join('; ');
53
51
  }
54
52
  else {
55
53
  return element.toString(keyedSegment[element.name]);
@@ -1,7 +1,10 @@
1
1
  import { encodeElements } from './encoder.js';
2
2
  import { SegmentHeaderGroup } from './segmentHeader.js';
3
3
  export class SegmentDefinition {
4
- id = this.constructor.name;
4
+ id;
5
+ constructor(id) {
6
+ this.id = id;
7
+ }
5
8
  static header = new SegmentHeaderGroup();
6
9
  getElementsForVersion(version) {
7
10
  return this.elements.filter((element) => version >= (element.minVersion ?? 0) && version <= (element.maxVersion ?? Number.MAX_SAFE_INTEGER));
@@ -7,8 +7,11 @@ import { BankIdentification } from '../dataGroups/BankIdentification.js';
7
7
  * General bank parameters
8
8
  */
9
9
  export class HIBPA extends SegmentDefinition {
10
- static Id = this.name;
10
+ static Id = 'HIBPA';
11
11
  version = 3;
12
+ constructor() {
13
+ super(HIBPA.Id);
14
+ }
12
15
  elements = [
13
16
  new Numeric('bpdVersion', 1, 1, 3),
14
17
  new BankIdentification('bank', 1, 1),
@@ -4,8 +4,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
4
4
  * Account transactions within period response
5
5
  */
6
6
  export class HIKAZ extends SegmentDefinition {
7
- static Id = this.name;
7
+ static Id = 'HIKAZ';
8
8
  version = 7;
9
+ constructor() {
10
+ super(HIKAZ.Id);
11
+ }
9
12
  elements = [
10
13
  new Binary('bookedTransactions', 1, 1, Number.MAX_SAFE_INTEGER),
11
14
  new Binary('notedTransactions', 0, 1, Number.MAX_SAFE_INTEGER),
@@ -5,9 +5,9 @@ import { BusinessTransactionParameter } from './businessTransactionParameter.js'
5
5
  * Parameters for HKKAZ business transaction
6
6
  */
7
7
  export class HIKAZS extends BusinessTransactionParameter {
8
- static Id = this.name;
8
+ static Id = 'HIKAZS';
9
9
  version = 7;
10
10
  constructor() {
11
- super([new Numeric('maxDays', 1, 1, 4), new YesNo('entryCountAllowed', 1, 1), new YesNo('allAccountsAllowed', 1, 1, 5)], 6);
11
+ super(HIKAZS.Id, [new Numeric('maxDays', 1, 1, 4), new YesNo('entryCountAllowed', 1, 1), new YesNo('allAccountsAllowed', 1, 1, 5)], 6);
12
12
  }
13
13
  }
@@ -5,7 +5,10 @@ import { SegmentDefinition } from '../segmentDefinition.js';
5
5
  * Information to the customer of the bank
6
6
  */
7
7
  export class HIKIM extends SegmentDefinition {
8
- static Id = this.name;
8
+ static Id = 'HIKIM';
9
9
  version = 2;
10
+ constructor() {
11
+ super(HIKIM.Id);
12
+ }
10
13
  elements = [new AlphaNumeric('subject', 1, 1, 35), new Text('text', 1, 1, 2048)];
11
14
  }
@@ -7,8 +7,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
7
7
  *
8
8
  */
9
9
  export class HIKOM extends SegmentDefinition {
10
- static Id = this.name;
10
+ static Id = 'HIKOM';
11
11
  version = 4;
12
+ constructor() {
13
+ super(HIKOM.Id);
14
+ }
12
15
  elements = [
13
16
  new BankIdentification('bank', 1, 1),
14
17
  new Numeric('defLang', 1, 1, 3),
@@ -7,10 +7,10 @@ import { BusinessTransactionParameter } from './businessTransactionParameter.js'
7
7
  * Parameters for PIN/TAN method
8
8
  */
9
9
  export class HIPINS extends BusinessTransactionParameter {
10
- static Id = this.name;
10
+ static Id = 'HIPINS';
11
11
  version = 1;
12
12
  constructor() {
13
- super([
13
+ super(HIPINS.Id, [
14
14
  new Numeric('minPinLen', 0, 1, 2),
15
15
  new Numeric('maxPinLen', 0, 1, 2),
16
16
  new Numeric('maxTanLen', 0, 1, 2),
@@ -6,8 +6,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
6
6
  * Responses to the message
7
7
  */
8
8
  export class HIRMG extends SegmentDefinition {
9
- static Id = this.name;
9
+ static Id = 'HIRMG';
10
10
  static Version = 2;
11
+ constructor() {
12
+ super(HIRMG.Id);
13
+ }
11
14
  version = HIRMG.Version;
12
15
  elements = [
13
16
  new DataGroup('answers', [
@@ -6,8 +6,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
6
6
  * Responses to the message
7
7
  */
8
8
  export class HIRMS extends SegmentDefinition {
9
- static Id = this.name;
9
+ static Id = 'HIRMS';
10
10
  static Version = 2;
11
+ constructor() {
12
+ super(HIRMS.Id);
13
+ }
11
14
  version = HIRMS.Version;
12
15
  elements = [
13
16
  new DataGroup('answers', [
@@ -11,8 +11,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
11
11
  * Account balances response
12
12
  */
13
13
  export class HISAL extends SegmentDefinition {
14
- static Id = this.name;
14
+ static Id = 'HISAL';
15
15
  version = 8;
16
+ constructor() {
17
+ super(HISAL.Id);
18
+ }
16
19
  elements = [
17
20
  new AccountGroup('account', 1, 1, 1, 6),
18
21
  new InternationalAccountGroup('account', 1, 1, 7),
@@ -5,8 +5,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
5
5
  * Synchonisation response
6
6
  */
7
7
  export class HISYN extends SegmentDefinition {
8
- static Id = this.name;
8
+ static Id = 'HISYN';
9
9
  version = 4;
10
+ constructor() {
11
+ super(HISYN.Id);
12
+ }
10
13
  elements = [
11
14
  new Identification('systemId', 0, 1),
12
15
  new Numeric('msgNr', 0, 1, 4),
@@ -10,7 +10,10 @@ import { SegmentDefinition } from '../segmentDefinition.js';
10
10
  * TAN media response
11
11
  */
12
12
  export class HITAB extends SegmentDefinition {
13
- static Id = this.name;
13
+ static Id = 'HITAB';
14
+ constructor() {
15
+ super(HITAB.Id);
16
+ }
14
17
  version = 5;
15
18
  elements = [
16
19
  new Numeric('tanUsage', 1, 1, 1),
@@ -8,8 +8,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
8
8
  * TAN response
9
9
  */
10
10
  export class HITAN extends SegmentDefinition {
11
- static Id = this.name;
11
+ static Id = 'HITAN';
12
12
  version = 7;
13
+ constructor() {
14
+ super(HITAN.Id);
15
+ }
13
16
  elements = [
14
17
  new AlphaNumeric('tanProcess', 1, 1, 1),
15
18
  new Binary('orderHash', 0, 1, 256),
@@ -8,10 +8,10 @@ import { BusinessTransactionParameter } from './businessTransactionParameter.js'
8
8
  * Parameters for two-step TAN methods
9
9
  */
10
10
  export class HITANS extends BusinessTransactionParameter {
11
- static Id = this.name;
11
+ static Id = 'HITANS';
12
12
  version = 7;
13
13
  constructor() {
14
- super([
14
+ super(HITANS.Id, [
15
15
  new YesNo('oneStepAllowed', 1, 1),
16
16
  new YesNo('multipleTansactions', 1, 1),
17
17
  new Numeric('hashMethod', 1, 1, 1),
@@ -6,8 +6,11 @@ import { Identification } from '../dataElements/Identification.js';
6
6
  * User parameters general
7
7
  */
8
8
  export class HIUPA extends SegmentDefinition {
9
- static Id = this.name;
9
+ static Id = 'HIUPA';
10
10
  version = 4;
11
+ constructor() {
12
+ super(HIUPA.Id);
13
+ }
11
14
  elements = [
12
15
  new Identification('internalUserId', 1, 1),
13
16
  new Numeric('updVersion', 1, 1, 3),
@@ -10,8 +10,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
10
10
  * User parameters account information
11
11
  */
12
12
  export class HIUPD extends SegmentDefinition {
13
- static Id = this.name;
13
+ static Id = 'HIUPD';
14
14
  version = 6;
15
+ constructor() {
16
+ super(HIUPD.Id);
17
+ }
15
18
  elements = [
16
19
  new AccountGroup('account', 0, 1),
17
20
  new AlphaNumeric('iban', 0, 1, 34),
@@ -0,0 +1,15 @@
1
+ import { Binary } from '../dataElements/Binary.js';
2
+ import { SegmentDefinition } from '../segmentDefinition.js';
3
+ /**
4
+ * Geschäftsvorfälle: C.4.3.1 Kreditinstitutsrückmeldung
5
+ * Version: 6
6
+ */
7
+ export class HIWPD extends SegmentDefinition {
8
+ static Id = 'HIWPD';
9
+ static Version = 6;
10
+ constructor() {
11
+ super(HIWPD.Id);
12
+ }
13
+ version = HIWPD.Version;
14
+ elements = [new Binary('portfolioStatement', 1, 1)];
15
+ }
@@ -4,8 +4,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
4
4
  * Dialog end
5
5
  */
6
6
  export class HKEND extends SegmentDefinition {
7
- static Id = this.name;
7
+ static Id = 'HKEND';
8
8
  static Version = 1;
9
+ constructor() {
10
+ super(HKEND.Id);
11
+ }
9
12
  version = HKEND.Version;
10
13
  elements = [new Identification('dialogId', 1, 1)];
11
14
  }
@@ -6,8 +6,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
6
6
  * Identification
7
7
  */
8
8
  export class HKIDN extends SegmentDefinition {
9
- static Id = this.name;
9
+ static Id = 'HKIDN';
10
10
  static Version = 2;
11
+ constructor() {
12
+ super(HKIDN.Id);
13
+ }
11
14
  version = HKIDN.Version;
12
15
  elements = [
13
16
  new BankIdentification('bank', 1, 1),
@@ -9,8 +9,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
9
9
  * Request account transactions in a given period
10
10
  */
11
11
  export class HKKAZ extends SegmentDefinition {
12
- static Id = this.name;
12
+ static Id = 'HKKAZ';
13
13
  static Version = 7;
14
+ constructor() {
15
+ super(HKKAZ.Id);
16
+ }
14
17
  version = HKKAZ.Version;
15
18
  elements = [
16
19
  new AccountGroup('account', 1, 1, 1, 6),
@@ -8,8 +8,11 @@ import { SegmentDefinition } from '../segmentDefinition.js';
8
8
  * Request Account balances
9
9
  */
10
10
  export class HKSAL extends SegmentDefinition {
11
- static Id = this.name;
11
+ static Id = 'HKSAL';
12
12
  static Version = 8;
13
+ constructor() {
14
+ super(HKSAL.Id);
15
+ }
13
16
  version = HKSAL.Version;
14
17
  elements = [
15
18
  new AccountGroup('account', 1, 1, 1, 6),