lib-fints 1.0.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 (306) hide show
  1. package/LICENSE +504 -0
  2. package/README.md +216 -0
  3. package/dist/accountBalance.js +1 -0
  4. package/dist/bankAccount.js +34 -0
  5. package/dist/bankAnswer.js +1 -0
  6. package/dist/bankTransaction.js +1 -0
  7. package/dist/bankingInformation.js +1 -0
  8. package/dist/bpd.js +1 -0
  9. package/dist/client.js +165 -0
  10. package/dist/codes.js +79 -0
  11. package/dist/config.js +181 -0
  12. package/dist/dataElements/AlphaNumeric.js +24 -0
  13. package/dist/dataElements/Amount.js +6 -0
  14. package/dist/dataElements/Binary.js +20 -0
  15. package/dist/dataElements/Country.js +6 -0
  16. package/dist/dataElements/Currency.js +6 -0
  17. package/dist/dataElements/Dat.js +18 -0
  18. package/dist/dataElements/DataElement.js +37 -0
  19. package/dist/dataElements/Digits.js +23 -0
  20. package/dist/dataElements/Float.js +21 -0
  21. package/dist/dataElements/Identification.js +6 -0
  22. package/dist/dataElements/Numeric.js +26 -0
  23. package/dist/dataElements/Text.js +21 -0
  24. package/dist/dataElements/Time.js +18 -0
  25. package/dist/dataElements/YesNo.js +18 -0
  26. package/dist/dataGroups/Account.js +12 -0
  27. package/dist/dataGroups/Balance.js +15 -0
  28. package/dist/dataGroups/BankIdentification.js +8 -0
  29. package/dist/dataGroups/DataGroup.js +54 -0
  30. package/dist/dataGroups/InternationalAccount.js +15 -0
  31. package/dist/dataGroups/Money.js +8 -0
  32. package/dist/dataGroups/RefMessage.js +8 -0
  33. package/dist/dataGroups/TimeStamp.js +8 -0
  34. package/dist/decoder.js +97 -0
  35. package/dist/dialog.js +189 -0
  36. package/dist/encoder.js +47 -0
  37. package/dist/format.js +6 -0
  38. package/dist/httpClient.js +41 -0
  39. package/dist/httpClientNode.js +59 -0
  40. package/dist/index.js +15 -0
  41. package/dist/interactions/balanceInteraction.js +47 -0
  42. package/dist/interactions/customerInteraction.js +55 -0
  43. package/dist/interactions/initDialogInteraction.js +155 -0
  44. package/dist/interactions/statementInteraction.js +44 -0
  45. package/dist/interactions/tanMediaInteraction.js +27 -0
  46. package/dist/message.js +198 -0
  47. package/dist/mt940parser.js +307 -0
  48. package/dist/parser.js +30 -0
  49. package/dist/partedSegment.js +8 -0
  50. package/dist/segment.js +59 -0
  51. package/dist/segmentDefinition.js +11 -0
  52. package/dist/segmentHeader.js +13 -0
  53. package/dist/segments/HIBPA.js +23 -0
  54. package/dist/segments/HIKAZ.js +13 -0
  55. package/dist/segments/HIKAZS.js +13 -0
  56. package/dist/segments/HIKIM.js +11 -0
  57. package/dist/segments/HIKOM.js +23 -0
  58. package/dist/segments/HIPINS.js +22 -0
  59. package/dist/segments/HIRMG.js +20 -0
  60. package/dist/segments/HIRMS.js +20 -0
  61. package/dist/segments/HISAL.js +31 -0
  62. package/dist/segments/HISYN.js +16 -0
  63. package/dist/segments/HITAB.js +37 -0
  64. package/dist/segments/HITAN.js +23 -0
  65. package/dist/segments/HITANS.js +48 -0
  66. package/dist/segments/HIUPA.js +18 -0
  67. package/dist/segments/HIUPD.js +34 -0
  68. package/dist/segments/HKEND.js +11 -0
  69. package/dist/segments/HKIDN.js +18 -0
  70. package/dist/segments/HKKAZ.js +24 -0
  71. package/dist/segments/HKSAL.js +21 -0
  72. package/dist/segments/HKSYN.js +11 -0
  73. package/dist/segments/HKTAB.js +12 -0
  74. package/dist/segments/HKTAN.js +35 -0
  75. package/dist/segments/HKVVB.js +18 -0
  76. package/dist/segments/HNHBK.js +20 -0
  77. package/dist/segments/HNHBS.js +11 -0
  78. package/dist/segments/HNSHA.js +17 -0
  79. package/dist/segments/HNSHK.js +43 -0
  80. package/dist/segments/HNVSD.js +11 -0
  81. package/dist/segments/HNVSK.js +45 -0
  82. package/dist/segments/businessTransactionParameter.js +20 -0
  83. package/dist/segments/registry.js +71 -0
  84. package/dist/tanMethod.js +1 -0
  85. package/dist/tests/HIBPA.test.js +26 -0
  86. package/dist/tests/HIPINS.test.js +14 -0
  87. package/dist/tests/HIRMG.test.js +24 -0
  88. package/dist/tests/HITAB.test.js +19 -0
  89. package/dist/tests/HITANS.test.js +19 -0
  90. package/dist/tests/HIUPA.test.js +11 -0
  91. package/dist/tests/HIUPD.test.js +11 -0
  92. package/dist/tests/HKIDN.test.js +22 -0
  93. package/dist/tests/HKSAL.test.js +45 -0
  94. package/dist/tests/HKTAN.test.js +21 -0
  95. package/dist/tests/HNSHK.test.js +11 -0
  96. package/dist/tests/HNVSK.test.js +11 -0
  97. package/dist/tests/client.test.js +33 -0
  98. package/dist/tests/datatypes.test.js +8 -0
  99. package/dist/tests/message.test.js +80 -0
  100. package/dist/tests/mt940parser.test.js +56 -0
  101. package/dist/tests/parser.test.js +20 -0
  102. package/dist/types/accountBalance.d.ts +9 -0
  103. package/dist/types/accountBalance.d.ts.map +1 -0
  104. package/dist/types/bankAccount.d.ts +27 -0
  105. package/dist/types/bankAccount.d.ts.map +1 -0
  106. package/dist/types/bankAnswer.d.ts +6 -0
  107. package/dist/types/bankAnswer.d.ts.map +1 -0
  108. package/dist/types/bankTransaction.d.ts +6 -0
  109. package/dist/types/bankTransaction.d.ts.map +1 -0
  110. package/dist/types/bankingInformation.d.ts +20 -0
  111. package/dist/types/bankingInformation.d.ts.map +1 -0
  112. package/dist/types/bpd.d.ts +17 -0
  113. package/dist/types/bpd.d.ts.map +1 -0
  114. package/dist/types/client.d.ts +86 -0
  115. package/dist/types/client.d.ts.map +1 -0
  116. package/dist/types/codes.d.ts +68 -0
  117. package/dist/types/codes.d.ts.map +1 -0
  118. package/dist/types/config.d.ts +99 -0
  119. package/dist/types/config.d.ts.map +1 -0
  120. package/dist/types/dataElements/AlphaNumeric.d.ts +8 -0
  121. package/dist/types/dataElements/AlphaNumeric.d.ts.map +1 -0
  122. package/dist/types/dataElements/Amount.d.ts +5 -0
  123. package/dist/types/dataElements/Amount.d.ts.map +1 -0
  124. package/dist/types/dataElements/Binary.d.ts +8 -0
  125. package/dist/types/dataElements/Binary.d.ts.map +1 -0
  126. package/dist/types/dataElements/Country.d.ts +5 -0
  127. package/dist/types/dataElements/Country.d.ts.map +1 -0
  128. package/dist/types/dataElements/Currency.d.ts +5 -0
  129. package/dist/types/dataElements/Currency.d.ts.map +1 -0
  130. package/dist/types/dataElements/Dat.d.ts +8 -0
  131. package/dist/types/dataElements/Dat.d.ts.map +1 -0
  132. package/dist/types/dataElements/DataElement.d.ts +14 -0
  133. package/dist/types/dataElements/DataElement.d.ts.map +1 -0
  134. package/dist/types/dataElements/Digits.d.ts +8 -0
  135. package/dist/types/dataElements/Digits.d.ts.map +1 -0
  136. package/dist/types/dataElements/Float.d.ts +8 -0
  137. package/dist/types/dataElements/Float.d.ts.map +1 -0
  138. package/dist/types/dataElements/Identification.d.ts +5 -0
  139. package/dist/types/dataElements/Identification.d.ts.map +1 -0
  140. package/dist/types/dataElements/Numeric.d.ts +9 -0
  141. package/dist/types/dataElements/Numeric.d.ts.map +1 -0
  142. package/dist/types/dataElements/Text.d.ts +8 -0
  143. package/dist/types/dataElements/Text.d.ts.map +1 -0
  144. package/dist/types/dataElements/Time.d.ts +8 -0
  145. package/dist/types/dataElements/Time.d.ts.map +1 -0
  146. package/dist/types/dataElements/YesNo.d.ts +7 -0
  147. package/dist/types/dataElements/YesNo.d.ts.map +1 -0
  148. package/dist/types/dataGroups/Account.d.ts +14 -0
  149. package/dist/types/dataGroups/Account.d.ts.map +1 -0
  150. package/dist/types/dataGroups/Balance.d.ts +12 -0
  151. package/dist/types/dataGroups/Balance.d.ts.map +1 -0
  152. package/dist/types/dataGroups/BankIdentification.d.ts +5 -0
  153. package/dist/types/dataGroups/BankIdentification.d.ts.map +1 -0
  154. package/dist/types/dataGroups/DataGroup.d.ts +10 -0
  155. package/dist/types/dataGroups/DataGroup.d.ts.map +1 -0
  156. package/dist/types/dataGroups/InternationalAccount.d.ts +13 -0
  157. package/dist/types/dataGroups/InternationalAccount.d.ts.map +1 -0
  158. package/dist/types/dataGroups/Money.d.ts +9 -0
  159. package/dist/types/dataGroups/Money.d.ts.map +1 -0
  160. package/dist/types/dataGroups/RefMessage.d.ts +9 -0
  161. package/dist/types/dataGroups/RefMessage.d.ts.map +1 -0
  162. package/dist/types/dataGroups/TimeStamp.d.ts +9 -0
  163. package/dist/types/dataGroups/TimeStamp.d.ts.map +1 -0
  164. package/dist/types/decoder.d.ts +4 -0
  165. package/dist/types/decoder.d.ts.map +1 -0
  166. package/dist/types/dialog.d.ts +21 -0
  167. package/dist/types/dialog.d.ts.map +1 -0
  168. package/dist/types/encoder.d.ts +3 -0
  169. package/dist/types/encoder.d.ts.map +1 -0
  170. package/dist/types/format.d.ts +3 -0
  171. package/dist/types/format.d.ts.map +1 -0
  172. package/dist/types/httpClient.d.ts +8 -0
  173. package/dist/types/httpClient.d.ts.map +1 -0
  174. package/dist/types/httpClientNode.d.ts +8 -0
  175. package/dist/types/httpClientNode.d.ts.map +1 -0
  176. package/dist/types/index.d.ts +17 -0
  177. package/dist/types/index.d.ts.map +1 -0
  178. package/dist/types/interactions/balanceInteraction.d.ts +15 -0
  179. package/dist/types/interactions/balanceInteraction.d.ts.map +1 -0
  180. package/dist/types/interactions/customerInteraction.d.ts +41 -0
  181. package/dist/types/interactions/customerInteraction.d.ts.map +1 -0
  182. package/dist/types/interactions/initDialogInteraction.d.ts +16 -0
  183. package/dist/types/interactions/initDialogInteraction.d.ts.map +1 -0
  184. package/dist/types/interactions/statementInteraction.d.ts +17 -0
  185. package/dist/types/interactions/statementInteraction.d.ts.map +1 -0
  186. package/dist/types/interactions/tanMediaInteraction.d.ts +13 -0
  187. package/dist/types/interactions/tanMediaInteraction.d.ts.map +1 -0
  188. package/dist/types/message.d.ts +30 -0
  189. package/dist/types/message.d.ts.map +1 -0
  190. package/dist/types/mt940parser.d.ts +83 -0
  191. package/dist/types/mt940parser.d.ts.map +1 -0
  192. package/dist/types/parser.d.ts +2 -0
  193. package/dist/types/parser.d.ts.map +1 -0
  194. package/dist/types/partedSegment.d.ts +14 -0
  195. package/dist/types/partedSegment.d.ts.map +1 -0
  196. package/dist/types/segment.d.ts +11 -0
  197. package/dist/types/segment.d.ts.map +1 -0
  198. package/dist/types/segmentDefinition.d.ts +11 -0
  199. package/dist/types/segmentDefinition.d.ts.map +1 -0
  200. package/dist/types/segmentHeader.d.ts +11 -0
  201. package/dist/types/segmentHeader.d.ts.map +1 -0
  202. package/dist/types/segments/HIBPA.d.ts +27 -0
  203. package/dist/types/segments/HIBPA.d.ts.map +1 -0
  204. package/dist/types/segments/HIKAZ.d.ts +16 -0
  205. package/dist/types/segments/HIKAZ.d.ts.map +1 -0
  206. package/dist/types/segments/HIKAZS.d.ts +16 -0
  207. package/dist/types/segments/HIKAZS.d.ts.map +1 -0
  208. package/dist/types/segments/HIKIM.d.ts +17 -0
  209. package/dist/types/segments/HIKIM.d.ts.map +1 -0
  210. package/dist/types/segments/HIKOM.d.ts +27 -0
  211. package/dist/types/segments/HIKOM.d.ts.map +1 -0
  212. package/dist/types/segments/HIPINS.d.ts +23 -0
  213. package/dist/types/segments/HIPINS.d.ts.map +1 -0
  214. package/dist/types/segments/HIRMG.d.ts +22 -0
  215. package/dist/types/segments/HIRMG.d.ts.map +1 -0
  216. package/dist/types/segments/HIRMS.d.ts +17 -0
  217. package/dist/types/segments/HIRMS.d.ts.map +1 -0
  218. package/dist/types/segments/HISAL.d.ts +32 -0
  219. package/dist/types/segments/HISAL.d.ts.map +1 -0
  220. package/dist/types/segments/HISYN.d.ts +19 -0
  221. package/dist/types/segments/HISYN.d.ts.map +1 -0
  222. package/dist/types/segments/HITAB.d.ts +39 -0
  223. package/dist/types/segments/HITAB.d.ts.map +1 -0
  224. package/dist/types/segments/HITAN.d.ts +25 -0
  225. package/dist/types/segments/HITAN.d.ts.map +1 -0
  226. package/dist/types/segments/HITANS.d.ts +41 -0
  227. package/dist/types/segments/HITANS.d.ts.map +1 -0
  228. package/dist/types/segments/HIUPA.d.ts +21 -0
  229. package/dist/types/segments/HIUPA.d.ts.map +1 -0
  230. package/dist/types/segments/HIUPD.d.ts +42 -0
  231. package/dist/types/segments/HIUPD.d.ts.map +1 -0
  232. package/dist/types/segments/HKEND.d.ts +16 -0
  233. package/dist/types/segments/HKEND.d.ts.map +1 -0
  234. package/dist/types/segments/HKIDN.d.ts +22 -0
  235. package/dist/types/segments/HKIDN.d.ts.map +1 -0
  236. package/dist/types/segments/HKKAZ.d.ts +25 -0
  237. package/dist/types/segments/HKKAZ.d.ts.map +1 -0
  238. package/dist/types/segments/HKSAL.d.ts +22 -0
  239. package/dist/types/segments/HKSAL.d.ts.map +1 -0
  240. package/dist/types/segments/HKSYN.d.ts +17 -0
  241. package/dist/types/segments/HKSYN.d.ts.map +1 -0
  242. package/dist/types/segments/HKTAB.d.ts +19 -0
  243. package/dist/types/segments/HKTAB.d.ts.map +1 -0
  244. package/dist/types/segments/HKTAN.d.ts +39 -0
  245. package/dist/types/segments/HKTAN.d.ts.map +1 -0
  246. package/dist/types/segments/HKVVB.d.ts +22 -0
  247. package/dist/types/segments/HKVVB.d.ts.map +1 -0
  248. package/dist/types/segments/HNHBK.d.ts +23 -0
  249. package/dist/types/segments/HNHBK.d.ts.map +1 -0
  250. package/dist/types/segments/HNHBS.d.ts +16 -0
  251. package/dist/types/segments/HNHBS.d.ts.map +1 -0
  252. package/dist/types/segments/HNSHA.d.ts +24 -0
  253. package/dist/types/segments/HNSHA.d.ts.map +1 -0
  254. package/dist/types/segments/HNSHK.d.ts +66 -0
  255. package/dist/types/segments/HNSHK.d.ts.map +1 -0
  256. package/dist/types/segments/HNVSD.d.ts +20 -0
  257. package/dist/types/segments/HNVSD.d.ts.map +1 -0
  258. package/dist/types/segments/HNVSK.d.ts +40 -0
  259. package/dist/types/segments/HNVSK.d.ts.map +1 -0
  260. package/dist/types/segments/businessTransactionParameter.d.ts +18 -0
  261. package/dist/types/segments/businessTransactionParameter.d.ts.map +1 -0
  262. package/dist/types/segments/registry.d.ts +4 -0
  263. package/dist/types/segments/registry.d.ts.map +1 -0
  264. package/dist/types/tanMethod.d.ts +10 -0
  265. package/dist/types/tanMethod.d.ts.map +1 -0
  266. package/dist/types/tests/HIBPA.test.d.ts +2 -0
  267. package/dist/types/tests/HIBPA.test.d.ts.map +1 -0
  268. package/dist/types/tests/HIPINS.test.d.ts +2 -0
  269. package/dist/types/tests/HIPINS.test.d.ts.map +1 -0
  270. package/dist/types/tests/HIRMG.test.d.ts +2 -0
  271. package/dist/types/tests/HIRMG.test.d.ts.map +1 -0
  272. package/dist/types/tests/HITAB.test.d.ts +2 -0
  273. package/dist/types/tests/HITAB.test.d.ts.map +1 -0
  274. package/dist/types/tests/HITANS.test.d.ts +2 -0
  275. package/dist/types/tests/HITANS.test.d.ts.map +1 -0
  276. package/dist/types/tests/HIUPA.test.d.ts +2 -0
  277. package/dist/types/tests/HIUPA.test.d.ts.map +1 -0
  278. package/dist/types/tests/HIUPD.test.d.ts +2 -0
  279. package/dist/types/tests/HIUPD.test.d.ts.map +1 -0
  280. package/dist/types/tests/HKIDN.test.d.ts +2 -0
  281. package/dist/types/tests/HKIDN.test.d.ts.map +1 -0
  282. package/dist/types/tests/HKSAL.test.d.ts +2 -0
  283. package/dist/types/tests/HKSAL.test.d.ts.map +1 -0
  284. package/dist/types/tests/HKTAN.test.d.ts +2 -0
  285. package/dist/types/tests/HKTAN.test.d.ts.map +1 -0
  286. package/dist/types/tests/HNSHK.test.d.ts +2 -0
  287. package/dist/types/tests/HNSHK.test.d.ts.map +1 -0
  288. package/dist/types/tests/HNVSK.test.d.ts +2 -0
  289. package/dist/types/tests/HNVSK.test.d.ts.map +1 -0
  290. package/dist/types/tests/client.test.d.ts +2 -0
  291. package/dist/types/tests/client.test.d.ts.map +1 -0
  292. package/dist/types/tests/datatypes.test.d.ts +2 -0
  293. package/dist/types/tests/datatypes.test.d.ts.map +1 -0
  294. package/dist/types/tests/message.test.d.ts +2 -0
  295. package/dist/types/tests/message.test.d.ts.map +1 -0
  296. package/dist/types/tests/mt940parser.test.d.ts +2 -0
  297. package/dist/types/tests/mt940parser.test.d.ts.map +1 -0
  298. package/dist/types/tests/parser.test.d.ts +2 -0
  299. package/dist/types/tests/parser.test.d.ts.map +1 -0
  300. package/dist/types/unknownSegment.d.ts +14 -0
  301. package/dist/types/unknownSegment.d.ts.map +1 -0
  302. package/dist/types/upd.d.ts +8 -0
  303. package/dist/types/upd.d.ts.map +1 -0
  304. package/dist/unknownSegment.js +8 -0
  305. package/dist/upd.js +1 -0
  306. package/package.json +45 -0
package/dist/config.js ADDED
@@ -0,0 +1,181 @@
1
+ import { getSegmentDefinition } from './segments/registry.js';
2
+ /**
3
+ * Configuration for the FinTS client
4
+ */
5
+ export class FinTSConfig {
6
+ productId;
7
+ productVersion;
8
+ url;
9
+ bankIdentification;
10
+ userId;
11
+ pin;
12
+ tanMethodId;
13
+ tanMediaName;
14
+ customerId;
15
+ country;
16
+ bankingInformation;
17
+ debugEnabled = false;
18
+ constructor(productId, productVersion, url, bankIdentification, userId, pin, bankingInformation, tanMethodId, tanMediaName, customerId, country = 280) {
19
+ this.productId = productId;
20
+ this.productVersion = productVersion;
21
+ this.url = url;
22
+ this.bankIdentification = bankIdentification;
23
+ this.userId = userId;
24
+ this.pin = pin;
25
+ this.tanMethodId = tanMethodId;
26
+ this.tanMediaName = tanMediaName;
27
+ this.customerId = customerId;
28
+ this.country = country;
29
+ if (!productId) {
30
+ throw Error('productId needs to be provided in configuration');
31
+ }
32
+ if (!bankingInformation) {
33
+ this.bankingInformation = {
34
+ systemId: '0',
35
+ bankMessages: [],
36
+ };
37
+ }
38
+ else {
39
+ this.bankingInformation = bankingInformation;
40
+ }
41
+ if (!this.bankingUrl) {
42
+ throw Error('bank URL needs to be provided in configuration');
43
+ }
44
+ if (!this.countryCode) {
45
+ throw Error('countryCode needs to be provided in configuration');
46
+ }
47
+ if (!this.bankId) {
48
+ throw Error('bank ID (BLZ) needs to be provided in configuration');
49
+ }
50
+ if (tanMethodId) {
51
+ this.selectTanMethod(tanMethodId);
52
+ }
53
+ if (tanMediaName) {
54
+ this.selectTanMedia(tanMediaName);
55
+ }
56
+ }
57
+ /**
58
+ * Factory method to create a configuration for the first time use i.e. no previous banking information is available
59
+ * @param productId The product ID obtained by registering with ZKA, see https://www.hbci-zka.de/register/prod_register.htm
60
+ * @param productVersion The version of your end product
61
+ * @param url The banks FinTS endpoint URL
62
+ * @param bankId The bank ID (BLZ)
63
+ * @param userId The user ID
64
+ * @param pin The PIN to authenticate the user
65
+ * @param customerId An optional customer ID when this is not the same as the user ID
66
+ * @param countryCode The country code of the bank, defaults to 280 (Germany)
67
+ * @returns a FinTS configuration
68
+ */
69
+ static forFirstTimeUse(productId, productVersion, url, bankId, userId, pin, customerId, countryCode = 280) {
70
+ return new FinTSConfig(productId, productVersion, url, bankId, userId, pin, undefined, undefined, undefined, customerId, countryCode);
71
+ }
72
+ /**
73
+ * Factory method to create a configuration from existing banking information
74
+ * @param productId The product ID obtained by registering with ZKA, see https://www.hbci-zka.de/register/prod_register.htm
75
+ * @param productVersion The version of your end product
76
+ * @param bankingInformation The banking information obtained from a previous synchronization
77
+ * @param userId The user ID
78
+ * @param pin The PIN to authenticate the user
79
+ * @param tanMethodId The ID of the TAN method to use, see config.availableTanMethods
80
+ * @param tanMediaName The name of the TAN media to use, see config.selectedTanMethod.activeTanMedia
81
+ * @param customerId An optional customer ID when this is not the same as the user ID
82
+ * @param countryCode The country code of the bank, defaults to 280 (Germany)
83
+ * @returns a FinTS configuration
84
+ */
85
+ static fromBankingInformation(productId, productVersion, bankingInformation, userId, pin, tanMethodId, tanMediaName, customerId, countryCode = 280) {
86
+ return new FinTSConfig(productId, productVersion, undefined, undefined, userId, pin, bankingInformation, tanMethodId, tanMediaName, customerId, countryCode);
87
+ }
88
+ /**
89
+ * The FinTS URL of the bank
90
+ */
91
+ get bankingUrl() {
92
+ return this.bankingInformation.bpd?.url ?? this.url;
93
+ }
94
+ /**
95
+ * The country code of the bank
96
+ */
97
+ get countryCode() {
98
+ return this.bankingInformation.bpd?.countryCode ?? this.country;
99
+ }
100
+ /**
101
+ * The bank ID (BLZ)
102
+ */
103
+ get bankId() {
104
+ return this.bankingInformation.bpd?.bankId ?? this.bankIdentification;
105
+ }
106
+ /**
107
+ * A list of all available TAN methods for the user
108
+ */
109
+ get availableTanMethods() {
110
+ return (this.bankingInformation.bpd?.supportedTanMethods?.filter((m) => this.bankingInformation.bpd?.availableTanMethodIds?.includes(m.id)) ?? []);
111
+ }
112
+ /**
113
+ * Selects a TAN method by its ID for the user, see also FinTSConfig#availableTanMethods
114
+ * @param tanMethodId The ID of the TAN method to select, corresponding to an ID in availableTanMethods
115
+ */
116
+ selectTanMethod(tanMethodId) {
117
+ if (!this.bankingInformation.bpd?.availableTanMethodIds?.find((id) => id === tanMethodId)) {
118
+ throw new Error(`TAN Method '${tanMethodId}' not found in the available TAN methods in the BPD`);
119
+ }
120
+ this.tanMethodId = tanMethodId;
121
+ }
122
+ /**
123
+ * Selects a TAN media by its name for the user
124
+ * @param tanMediaName The name of the TAN media, corresponding to a name in selectedTanMethod.activeTanMedia
125
+ */
126
+ selectTanMedia(tanMediaName) {
127
+ if (tanMediaName && !this.tanMethodId) {
128
+ throw new Error('tanMediaName can only be used when a TAN method is also selected');
129
+ }
130
+ if (tanMediaName && !this.selectedTanMethod?.activeTanMedia?.includes(tanMediaName)) {
131
+ throw new Error(`TAN media '${tanMediaName}' not found in the active TAN media list for the selected TAN method`);
132
+ }
133
+ this.tanMediaName = tanMediaName;
134
+ }
135
+ /**
136
+ * The currently selected TAN method for the user
137
+ */
138
+ get selectedTanMethod() {
139
+ return this.availableTanMethods.find((t) => t.id === this.tanMethodId);
140
+ }
141
+ /**
142
+ * Checks if a transaction is supported by the bank
143
+ * @param transId The transaction ID
144
+ */
145
+ isTransactionSupported(transId) {
146
+ return this.bankingInformation.bpd?.allowedTransactions.find((t) => t.transId === transId) !== undefined;
147
+ }
148
+ /**
149
+ * Checks if a transaction is supported for a specific account
150
+ * @param accountNumber The account number
151
+ * @param transId The transaction ID
152
+ */
153
+ isAccountTransactionSupported(accountNumber, transId) {
154
+ const bankAccount = this.getBankAccount(accountNumber);
155
+ return !!bankAccount.allowedTransactions?.find((t) => t.transId === transId);
156
+ }
157
+ /**
158
+ * Gets the maximum supported transaction version of a transaction, considering this client's support and the bank's support
159
+ * @param transId The transaction ID
160
+ */
161
+ getMaxSupportedTransactionVersion(transId) {
162
+ const definition = getSegmentDefinition(transId);
163
+ if (!definition) {
164
+ throw new Error(`segment definition for ${transId} not registered`);
165
+ }
166
+ const allowedVersions = this.bankingInformation.bpd?.allowedTransactions.find((t) => t.transId === transId)?.versions ?? [];
167
+ const maxSupportedversion = allowedVersions.sort().findLast((version) => version <= definition.version) ?? undefined;
168
+ return maxSupportedversion;
169
+ }
170
+ /**
171
+ * Gets the bank account information for a specific account number
172
+ * @param accountNumber The account number
173
+ */
174
+ getBankAccount(accountNumber) {
175
+ const bankAccount = this.bankingInformation.upd?.bankAccounts.find((a) => a.accountNumber === accountNumber);
176
+ if (!bankAccount) {
177
+ throw Error(`Account ${accountNumber} not found in UPD`);
178
+ }
179
+ return bankAccount;
180
+ }
181
+ }
@@ -0,0 +1,24 @@
1
+ import { DataElement } from './DataElement.js';
2
+ import { finTsDecode, finTsEncode } from '../format.js';
3
+ export class AlphaNumeric extends DataElement {
4
+ maxLength;
5
+ constructor(name, minCount = 0, maxCount = 1, maxLength, minVersion, maxVersion) {
6
+ super(name, minCount, maxCount, minVersion, maxVersion);
7
+ this.maxLength = maxLength;
8
+ }
9
+ encode(value) {
10
+ if (!value) {
11
+ return '';
12
+ }
13
+ if (value.indexOf('\n') >= 0 || value.indexOf('\r') >= 0) {
14
+ throw Error(`the AlphaNumeric value '${this.name}' must not contain CR or LF characters`);
15
+ }
16
+ if (this.maxLength && value.toString().length > this.maxLength) {
17
+ throw Error(`the AlphaNumeric value '${this.name}' must not exceed its maximum length`);
18
+ }
19
+ return finTsEncode(value.trim());
20
+ }
21
+ decode(text) {
22
+ return finTsDecode(text);
23
+ }
24
+ }
@@ -0,0 +1,6 @@
1
+ import { Float } from './Float.js';
2
+ export class Amount extends Float {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, 15, minVersion, maxVersion);
5
+ }
6
+ }
@@ -0,0 +1,20 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class Binary extends DataElement {
3
+ maxLength;
4
+ constructor(name, minCount = 0, maxCount = 1, maxLength, minVersion, maxVersion) {
5
+ super(name, minCount, maxCount, minVersion, maxVersion);
6
+ this.maxLength = maxLength;
7
+ }
8
+ encode(value) {
9
+ if (!value) {
10
+ return '';
11
+ }
12
+ if (this.maxLength && value.length > this.maxLength) {
13
+ throw Error(`the Binary value '${this.name}' must not exceed its maximum length`);
14
+ }
15
+ return `@${value.length}@${value}`;
16
+ }
17
+ decode(text) {
18
+ return text.slice(text.indexOf('@', 1) + 1);
19
+ }
20
+ }
@@ -0,0 +1,6 @@
1
+ import { Digits } from './Digits.js';
2
+ export class Country extends Digits {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, 3, minVersion, maxVersion);
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ import { AlphaNumeric } from './AlphaNumeric.js';
2
+ export class Currency extends AlphaNumeric {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, 3, minVersion, maxVersion);
5
+ }
6
+ }
@@ -0,0 +1,18 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class Dat extends DataElement {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, minVersion, maxVersion);
5
+ }
6
+ encode(value) {
7
+ if (!value) {
8
+ return '';
9
+ }
10
+ return value.toISOString().substring(0, 10).replaceAll('-', '');
11
+ }
12
+ decode(text) {
13
+ return new Date(`${text.substring(0, 4)}-${text.substring(4, 6)}-${text.substring(6)}`);
14
+ }
15
+ toString(value) {
16
+ return super.toString(value?.toDateString());
17
+ }
18
+ }
@@ -0,0 +1,37 @@
1
+ export class DataElement {
2
+ name;
3
+ minCount;
4
+ maxCount;
5
+ minVersion;
6
+ maxVersion;
7
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
8
+ this.name = name;
9
+ this.minCount = minCount;
10
+ this.maxCount = maxCount;
11
+ this.minVersion = minVersion;
12
+ this.maxVersion = maxVersion;
13
+ if (minCount < 0 || maxCount < 0 || minCount > maxCount) {
14
+ throw new Error('invalid count range');
15
+ }
16
+ if (minVersion && maxVersion && minVersion > maxVersion) {
17
+ throw new Error('invalid version range');
18
+ }
19
+ }
20
+ maxValueCount(version) {
21
+ return this.isInVersion(version) ? 1 : 0;
22
+ }
23
+ isInVersion(version) {
24
+ return (!this.minVersion || version >= this.minVersion) && (!this.maxVersion || version <= this.maxVersion);
25
+ }
26
+ toString(value) {
27
+ if (value !== undefined && value !== null && value !== '') {
28
+ return `${this.name}: ${value}`;
29
+ }
30
+ else if (this.minCount > 0) {
31
+ return `${this.name}: <MISSING>`;
32
+ }
33
+ else {
34
+ return '';
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,23 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class Digits extends DataElement {
3
+ digits;
4
+ constructor(name, minCount = 0, maxCount = 1, digits, minVersion, maxVersion) {
5
+ super(name, minCount, maxCount, minVersion, maxVersion);
6
+ this.digits = digits;
7
+ }
8
+ encode(value) {
9
+ if (this.digits < 1) {
10
+ throw Error('the number of digits in a Digits value must be greatet than zero');
11
+ }
12
+ if (!Number.isInteger(value) || value < 0) {
13
+ throw Error(`the Digits value '${this.name}' must be a positive integer`);
14
+ }
15
+ if (String(value).length > this.digits) {
16
+ throw Error(`the Digits value '${this.name}' must fit into the given number of digits`);
17
+ }
18
+ return value.toString().padStart(this.digits, '0');
19
+ }
20
+ decode(text) {
21
+ return Number.parseInt(text);
22
+ }
23
+ }
@@ -0,0 +1,21 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class Float extends DataElement {
3
+ maxLength;
4
+ constructor(name, minCount = 0, maxCount = 1, maxLength, minVersion, maxVersion) {
5
+ super(name, minCount, maxCount, minVersion, maxVersion);
6
+ this.maxLength = maxLength;
7
+ }
8
+ encode(value) {
9
+ if (value < 0) {
10
+ throw Error(`the Float value '${this.name}' must be positive`);
11
+ }
12
+ if (this.maxLength && value.toString().length > this.maxLength) {
13
+ throw Error(`the Float value '${this.name}' must not exceed its maximum length`);
14
+ }
15
+ const text = value.toString().replace('.', ',');
16
+ return text.indexOf(',') >= 0 ? text : text + ',';
17
+ }
18
+ decode(text) {
19
+ return Number.parseFloat(text.replace(',', '.'));
20
+ }
21
+ }
@@ -0,0 +1,6 @@
1
+ import { AlphaNumeric } from './AlphaNumeric.js';
2
+ export class Identification extends AlphaNumeric {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, 30, minVersion, maxVersion);
5
+ }
6
+ }
@@ -0,0 +1,26 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class Numeric extends DataElement {
3
+ maxLength;
4
+ constructor(name, minCount = 0, maxCount = 1, maxLength, minVersion, maxVersion) {
5
+ super(name, minCount, maxCount, minVersion, maxVersion);
6
+ this.maxLength = maxLength;
7
+ }
8
+ encode(value) {
9
+ if (value === undefined || value === null) {
10
+ return '';
11
+ }
12
+ if (!Number.isInteger(value) || value < 0) {
13
+ throw Error(`the Numeric value '${this.name}' must be a positive integer`);
14
+ }
15
+ if (this.maxLength && value.toString().length > this.maxLength) {
16
+ throw Error(`the Numeric value '${this.name}' must not exceed its maximum length`);
17
+ }
18
+ return value.toString();
19
+ }
20
+ decode(text) {
21
+ return Number.parseInt(text);
22
+ }
23
+ static decode(text) {
24
+ return Number.parseInt(text);
25
+ }
26
+ }
@@ -0,0 +1,21 @@
1
+ import { DataElement } from './DataElement.js';
2
+ import { finTsDecode, finTsEncode } from '../format.js';
3
+ export class Text extends DataElement {
4
+ maxLength;
5
+ constructor(name, minCount = 0, maxCount = 1, maxLength, minVersion, maxVersion) {
6
+ super(name, minCount, maxCount, minVersion, maxVersion);
7
+ this.maxLength = maxLength;
8
+ }
9
+ encode(value) {
10
+ if (!value) {
11
+ return '';
12
+ }
13
+ if (this.maxLength && value.length > this.maxLength) {
14
+ throw Error('a Text value must not exceed its maximum length');
15
+ }
16
+ return finTsEncode(value.trim());
17
+ }
18
+ decode(text) {
19
+ return finTsDecode(text);
20
+ }
21
+ }
@@ -0,0 +1,18 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class Time extends DataElement {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, minVersion, maxVersion);
5
+ }
6
+ encode(value) {
7
+ if (!value) {
8
+ return '';
9
+ }
10
+ return value.toISOString().substring(11, 19).replaceAll(':', '');
11
+ }
12
+ decode(text) {
13
+ return new Date(`1970-01-01T${text.substring(0, 2)}:${text.substring(2, 4)}:${text.substring(4)}Z`);
14
+ }
15
+ toString(value) {
16
+ return super.toString(value?.toTimeString());
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ import { DataElement } from './DataElement.js';
2
+ export class YesNo extends DataElement {
3
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
4
+ super(name, minCount, maxCount, minVersion, maxVersion);
5
+ }
6
+ encode(value) {
7
+ if (value === undefined || value === null) {
8
+ return '';
9
+ }
10
+ return value ? 'J' : 'N';
11
+ }
12
+ decode(text) {
13
+ if (text !== 'J' && text !== 'N') {
14
+ throw Error(`the YesNo value '${this.name}' must be the character J or N`);
15
+ }
16
+ return text === 'J';
17
+ }
18
+ }
@@ -0,0 +1,12 @@
1
+ import { DataGroup } from './DataGroup.js';
2
+ import { Identification } from '../dataElements/Identification.js';
3
+ import { BankIdentification } from './BankIdentification.js';
4
+ export class AccountGroup extends DataGroup {
5
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
6
+ super(name, [
7
+ new Identification('accountNumber', 1, 1),
8
+ new Identification('subAccountId', 0, 1),
9
+ new BankIdentification('bank', 1, 1),
10
+ ], minCount, maxCount, minVersion, maxVersion);
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ import { Time } from '../dataElements/Time.js';
2
+ import { Dat } from '../dataElements/Dat.js';
3
+ import { AlphaNumeric } from '../dataElements/AlphaNumeric.js';
4
+ import { DataGroup } from './DataGroup.js';
5
+ import { MoneyGroup } from './Money.js';
6
+ export class BalanceGroup extends DataGroup {
7
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
8
+ super(name, [
9
+ new AlphaNumeric('creditDebit', 1, 1, 1),
10
+ new MoneyGroup('amount', 1, 1),
11
+ new Dat('date', 1, 1),
12
+ new Time('time', 0, 1),
13
+ ], minCount, maxCount, minVersion, maxVersion);
14
+ }
15
+ }
@@ -0,0 +1,8 @@
1
+ import { AlphaNumeric } from '../dataElements/AlphaNumeric.js';
2
+ import { DataGroup } from './DataGroup.js';
3
+ import { Country } from '../dataElements/Country.js';
4
+ export class BankIdentification extends DataGroup {
5
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
6
+ super(name, [new Country('country', 1, 1), new AlphaNumeric('bankId', 1, 1, 30)], minCount, maxCount, minVersion, maxVersion);
7
+ }
8
+ }
@@ -0,0 +1,54 @@
1
+ import { DataElement } from '../dataElements/DataElement.js';
2
+ import { decodeElements } from '../decoder.js';
3
+ import { encodeElements } from '../encoder.js';
4
+ export class DataGroup extends DataElement {
5
+ elements;
6
+ constructor(name, elements, minCount = 0, maxCount = 1, minVersion, maxVersion) {
7
+ super(name, minCount, maxCount, minVersion, maxVersion);
8
+ this.elements = elements;
9
+ if (!Array.isArray(elements)) {
10
+ throw new Error('a FinTS data group must be initialized with an array');
11
+ }
12
+ if (elements.length <= 0) {
13
+ throw new Error('cannot create a FinTS data group with no elements');
14
+ }
15
+ }
16
+ maxValueCount(version) {
17
+ return this.elements.reduce((count, element) => count + element.maxValueCount(version), 0);
18
+ }
19
+ encode(values, context, version) {
20
+ if (!version) {
21
+ throw new Error('version is required for encoding an element group');
22
+ }
23
+ const isSingleArray = this.elements.length === 1 && this.elements[0].maxCount > 1;
24
+ return encodeElements(isSingleArray ? [values] : values, this.elements, ':', version, [...context, this.name]);
25
+ }
26
+ decode(text, version) {
27
+ if (!text.replaceAll(':', '')) {
28
+ return undefined;
29
+ }
30
+ if (!version) {
31
+ throw new Error('version is required for decoding an element group');
32
+ }
33
+ return decodeElements(text, this.elements, ':', version, this.name);
34
+ }
35
+ toString(values) {
36
+ if (!values) {
37
+ return '';
38
+ }
39
+ let texts = this.elements.map((element) => {
40
+ if (element.maxCount > 1) {
41
+ if (this.elements.length === 1) {
42
+ return values.map((value) => element.toString(value)).join('; ');
43
+ }
44
+ else {
45
+ return values[element.name]?.map((value) => element.toString(value)).join('; ') ?? '';
46
+ }
47
+ }
48
+ else {
49
+ return element.toString(values[element.name]);
50
+ }
51
+ });
52
+ return `[${texts.filter((text) => !!text).join(', ')}]`;
53
+ }
54
+ }
@@ -0,0 +1,15 @@
1
+ import { AlphaNumeric } from '../dataElements/AlphaNumeric.js';
2
+ import { DataGroup } from './DataGroup.js';
3
+ import { Identification } from '../dataElements/Identification.js';
4
+ import { BankIdentification } from './BankIdentification.js';
5
+ export class InternationalAccountGroup extends DataGroup {
6
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
7
+ super(name, [
8
+ new AlphaNumeric('iban', 0, 1, 34),
9
+ new AlphaNumeric('bic', 0, 1, 11),
10
+ new Identification('accountNumber', 0, 1),
11
+ new Identification('subAccountId', 0, 1),
12
+ new BankIdentification('bank', 0, 1),
13
+ ], minCount, maxCount, minVersion, maxVersion);
14
+ }
15
+ }
@@ -0,0 +1,8 @@
1
+ import { DataGroup } from './DataGroup.js';
2
+ import { Amount } from '../dataElements/Amount.js';
3
+ import { Currency } from '../dataElements/Currency.js';
4
+ export class MoneyGroup extends DataGroup {
5
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
6
+ super(name, [new Amount('value', 1, 1), new Currency('currency', 1, 1)], minCount, maxCount, minVersion, maxVersion);
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ import { Numeric } from '../dataElements/Numeric.js';
2
+ import { DataGroup } from './DataGroup.js';
3
+ import { Identification } from '../dataElements/Identification.js';
4
+ export class RefMessageGroup extends DataGroup {
5
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
6
+ super(name, [new Identification('dialogId', 1, 1), new Numeric('msgNr', 1, 1, 4)], minCount, maxCount, minVersion, maxVersion);
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ import { Time } from '../dataElements/Time.js';
2
+ import { Dat } from '../dataElements/Dat.js';
3
+ import { DataGroup } from './DataGroup.js';
4
+ export class TimeStampGroup extends DataGroup {
5
+ constructor(name, minCount = 0, maxCount = 1, minVersion, maxVersion) {
6
+ super(name, [new Dat('date', 1, 1), new Time('time', 0, 1)], minCount, maxCount, minVersion, maxVersion);
7
+ }
8
+ }