@coderoftime/fints 0.1.0 → 0.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 (272) hide show
  1. package/CHANGELOG.md +142 -1
  2. package/README.md +127 -37
  3. package/dist/client.d.ts +48 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +199 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/core/account.d.ts +35 -7
  8. package/dist/core/account.d.ts.map +1 -1
  9. package/dist/core/account.js +84 -13
  10. package/dist/core/account.js.map +1 -1
  11. package/dist/core/amount.d.ts +2 -1
  12. package/dist/core/amount.d.ts.map +1 -1
  13. package/dist/core/amount.js +4 -1
  14. package/dist/core/amount.js.map +1 -1
  15. package/dist/core/balance.d.ts +1 -0
  16. package/dist/core/balance.d.ts.map +1 -1
  17. package/dist/core/balance.js +6 -5
  18. package/dist/core/balance.js.map +1 -1
  19. package/dist/core/bank-info.d.ts +1 -1
  20. package/dist/core/bank-info.js +1 -1
  21. package/dist/core/client.d.ts +50 -15
  22. package/dist/core/client.d.ts.map +1 -1
  23. package/dist/core/config.d.ts +28 -16
  24. package/dist/core/config.d.ts.map +1 -1
  25. package/dist/core/config.js +66 -26
  26. package/dist/core/config.js.map +1 -1
  27. package/dist/core/errors.d.ts +85 -23
  28. package/dist/core/errors.d.ts.map +1 -1
  29. package/dist/core/errors.js +112 -47
  30. package/dist/core/errors.js.map +1 -1
  31. package/dist/core/feedback.d.ts +4 -1
  32. package/dist/core/feedback.d.ts.map +1 -1
  33. package/dist/core/feedback.js +4 -1
  34. package/dist/core/feedback.js.map +1 -1
  35. package/dist/core/transaction.d.ts +6 -1
  36. package/dist/core/transaction.d.ts.map +1 -1
  37. package/dist/core/transaction.js +9 -4
  38. package/dist/core/transaction.js.map +1 -1
  39. package/dist/core/transport.d.ts +33 -6
  40. package/dist/core/transport.d.ts.map +1 -1
  41. package/dist/core/transport.js +77 -20
  42. package/dist/core/transport.js.map +1 -1
  43. package/dist/formats/camt.d.ts +24 -4
  44. package/dist/formats/camt.d.ts.map +1 -1
  45. package/dist/formats/camt.js +124 -41
  46. package/dist/formats/camt.js.map +1 -1
  47. package/dist/formats/mt940.d.ts +15 -3
  48. package/dist/formats/mt940.d.ts.map +1 -1
  49. package/dist/formats/mt940.js +161 -82
  50. package/dist/formats/mt940.js.map +1 -1
  51. package/dist/formats/readers.d.ts +6 -2
  52. package/dist/formats/readers.d.ts.map +1 -1
  53. package/dist/formats/readers.js +24 -29
  54. package/dist/formats/readers.js.map +1 -1
  55. package/dist/formats/record-budget.d.ts +7 -0
  56. package/dist/formats/record-budget.d.ts.map +1 -0
  57. package/dist/formats/record-budget.js +17 -0
  58. package/dist/formats/record-budget.js.map +1 -0
  59. package/dist/formats/sepa-purpose.d.ts +6 -0
  60. package/dist/formats/sepa-purpose.d.ts.map +1 -1
  61. package/dist/formats/sepa-purpose.js +23 -2
  62. package/dist/formats/sepa-purpose.js.map +1 -1
  63. package/dist/index.d.ts +3 -3
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +2 -2
  66. package/dist/index.js.map +1 -1
  67. package/dist/session/app-approval.d.ts +11 -5
  68. package/dist/session/app-approval.d.ts.map +1 -1
  69. package/dist/session/app-approval.js +23 -12
  70. package/dist/session/app-approval.js.map +1 -1
  71. package/dist/session/dialog-runner.d.ts +7 -10
  72. package/dist/session/dialog-runner.d.ts.map +1 -1
  73. package/dist/session/dialog-runner.js +15 -16
  74. package/dist/session/dialog-runner.js.map +1 -1
  75. package/dist/session/login-guard.d.ts +54 -49
  76. package/dist/session/login-guard.d.ts.map +1 -1
  77. package/dist/session/login-guard.js +156 -84
  78. package/dist/session/login-guard.js.map +1 -1
  79. package/dist/session/sepa-accounts.d.ts +20 -14
  80. package/dist/session/sepa-accounts.d.ts.map +1 -1
  81. package/dist/session/sepa-accounts.js +62 -46
  82. package/dist/session/sepa-accounts.js.map +1 -1
  83. package/dist/session/session-setup.d.ts +33 -25
  84. package/dist/session/session-setup.d.ts.map +1 -1
  85. package/dist/session/session-setup.js +87 -65
  86. package/dist/session/session-setup.js.map +1 -1
  87. package/dist/session/session-state.d.ts +9 -6
  88. package/dist/session/session-state.d.ts.map +1 -1
  89. package/dist/session/session-state.js +52 -17
  90. package/dist/session/session-state.js.map +1 -1
  91. package/dist/session/signed-dialog.d.ts +77 -0
  92. package/dist/session/signed-dialog.d.ts.map +1 -0
  93. package/dist/session/signed-dialog.js +170 -0
  94. package/dist/session/signed-dialog.js.map +1 -0
  95. package/dist/session/tan-selection.d.ts +26 -18
  96. package/dist/session/tan-selection.d.ts.map +1 -1
  97. package/dist/session/tan-selection.js +44 -33
  98. package/dist/session/tan-selection.js.map +1 -1
  99. package/dist/session/user-prompts.d.ts +8 -4
  100. package/dist/session/user-prompts.d.ts.map +1 -1
  101. package/dist/session/user-prompts.js +34 -14
  102. package/dist/session/user-prompts.js.map +1 -1
  103. package/dist/tan/challenge.d.ts +34 -13
  104. package/dist/tan/challenge.d.ts.map +1 -1
  105. package/dist/tan/challenge.js +25 -26
  106. package/dist/tan/challenge.js.map +1 -1
  107. package/dist/tan/flicker.d.ts +7 -1
  108. package/dist/tan/flicker.d.ts.map +1 -1
  109. package/dist/tan/flicker.js +40 -6
  110. package/dist/tan/flicker.js.map +1 -1
  111. package/dist/tan/tan-image.d.ts +3 -2
  112. package/dist/tan/tan-image.d.ts.map +1 -1
  113. package/dist/tan/tan-image.js +7 -5
  114. package/dist/tan/tan-image.js.map +1 -1
  115. package/dist/tan/tan-models.d.ts +5 -1
  116. package/dist/tan/tan-models.d.ts.map +1 -1
  117. package/dist/tan/tan-models.js +10 -5
  118. package/dist/tan/tan-models.js.map +1 -1
  119. package/dist/util/async.d.ts +0 -2
  120. package/dist/util/async.d.ts.map +1 -1
  121. package/dist/util/async.js +0 -4
  122. package/dist/util/async.js.map +1 -1
  123. package/dist/util/bytes.d.ts +2 -3
  124. package/dist/util/bytes.d.ts.map +1 -1
  125. package/dist/util/bytes.js +12 -20
  126. package/dist/util/bytes.js.map +1 -1
  127. package/dist/util/call-context.d.ts.map +1 -1
  128. package/dist/util/call-context.js +3 -2
  129. package/dist/util/call-context.js.map +1 -1
  130. package/dist/util/dates.d.ts +9 -16
  131. package/dist/util/dates.d.ts.map +1 -1
  132. package/dist/util/dates.js +39 -19
  133. package/dist/util/dates.js.map +1 -1
  134. package/dist/util/errors.d.ts +9 -1
  135. package/dist/util/errors.d.ts.map +1 -1
  136. package/dist/util/errors.js +12 -3
  137. package/dist/util/errors.js.map +1 -1
  138. package/dist/util/json.d.ts +4 -0
  139. package/dist/util/json.d.ts.map +1 -1
  140. package/dist/util/json.js +18 -0
  141. package/dist/util/json.js.map +1 -1
  142. package/dist/util/text.d.ts +21 -4
  143. package/dist/util/text.d.ts.map +1 -1
  144. package/dist/util/text.js +42 -13
  145. package/dist/util/text.js.map +1 -1
  146. package/dist/util/xml.d.ts +4 -3
  147. package/dist/util/xml.d.ts.map +1 -1
  148. package/dist/util/xml.js +37 -26
  149. package/dist/util/xml.js.map +1 -1
  150. package/dist/v3/account-extension.d.ts.map +1 -1
  151. package/dist/v3/account-extension.js +7 -10
  152. package/dist/v3/account-extension.js.map +1 -1
  153. package/dist/v3/bank-connection.d.ts +34 -0
  154. package/dist/v3/bank-connection.d.ts.map +1 -0
  155. package/dist/v3/bank-connection.js +58 -0
  156. package/dist/v3/bank-connection.js.map +1 -0
  157. package/dist/v3/dialog.d.ts +80 -46
  158. package/dist/v3/dialog.d.ts.map +1 -1
  159. package/dist/v3/dialog.js +162 -59
  160. package/dist/v3/dialog.js.map +1 -1
  161. package/dist/v3/message.d.ts +17 -4
  162. package/dist/v3/message.d.ts.map +1 -1
  163. package/dist/v3/message.js +62 -18
  164. package/dist/v3/message.js.map +1 -1
  165. package/dist/v3/parameter-store.d.ts +75 -0
  166. package/dist/v3/parameter-store.d.ts.map +1 -0
  167. package/dist/v3/parameter-store.js +143 -0
  168. package/dist/v3/parameter-store.js.map +1 -0
  169. package/dist/v3/parameters.d.ts +38 -12
  170. package/dist/v3/parameters.d.ts.map +1 -1
  171. package/dist/v3/parameters.js +91 -37
  172. package/dist/v3/parameters.js.map +1 -1
  173. package/dist/v3/protocol.d.ts +43 -50
  174. package/dist/v3/protocol.d.ts.map +1 -1
  175. package/dist/v3/protocol.js +58 -208
  176. package/dist/v3/protocol.js.map +1 -1
  177. package/dist/v3/queries.d.ts +51 -0
  178. package/dist/v3/queries.d.ts.map +1 -0
  179. package/dist/v3/queries.js +120 -0
  180. package/dist/v3/queries.js.map +1 -0
  181. package/dist/v3/segments.d.ts +29 -12
  182. package/dist/v3/segments.d.ts.map +1 -1
  183. package/dist/v3/segments.js +65 -23
  184. package/dist/v3/segments.js.map +1 -1
  185. package/dist/v3/syntax.d.ts +65 -14
  186. package/dist/v3/syntax.d.ts.map +1 -1
  187. package/dist/v3/syntax.js +167 -101
  188. package/dist/v3/syntax.js.map +1 -1
  189. package/package.json +10 -6
  190. package/src/client.ts +252 -0
  191. package/src/core/account.ts +86 -13
  192. package/src/core/amount.ts +3 -1
  193. package/src/core/balance.ts +6 -5
  194. package/src/core/bank-info.ts +1 -1
  195. package/src/core/client.ts +52 -15
  196. package/src/core/config.ts +69 -28
  197. package/src/core/errors.ts +122 -48
  198. package/src/core/feedback.ts +4 -1
  199. package/src/core/transaction.ts +9 -4
  200. package/src/core/transport.ts +98 -23
  201. package/src/formats/camt.ts +136 -39
  202. package/src/formats/mt940.ts +167 -81
  203. package/src/formats/readers.ts +24 -31
  204. package/src/formats/record-budget.ts +18 -0
  205. package/src/formats/sepa-purpose.ts +21 -2
  206. package/src/index.ts +4 -2
  207. package/src/session/app-approval.ts +51 -38
  208. package/src/session/dialog-runner.ts +31 -28
  209. package/src/session/login-guard.ts +174 -88
  210. package/src/session/sepa-accounts.ts +63 -45
  211. package/src/session/session-setup.ts +90 -71
  212. package/src/session/session-state.ts +56 -22
  213. package/src/session/signed-dialog.ts +192 -0
  214. package/src/session/tan-selection.ts +50 -39
  215. package/src/session/user-prompts.ts +35 -16
  216. package/src/tan/challenge.ts +40 -31
  217. package/src/tan/flicker.ts +44 -6
  218. package/src/tan/tan-image.ts +7 -5
  219. package/src/tan/tan-models.ts +10 -5
  220. package/src/util/async.ts +0 -5
  221. package/src/util/bytes.ts +13 -19
  222. package/src/util/call-context.ts +3 -2
  223. package/src/util/dates.ts +41 -24
  224. package/src/util/errors.ts +14 -3
  225. package/src/util/json.ts +16 -0
  226. package/src/util/text.ts +42 -12
  227. package/src/util/xml.ts +37 -26
  228. package/src/v3/account-extension.ts +7 -12
  229. package/src/v3/bank-connection.ts +67 -0
  230. package/src/v3/dialog.ts +175 -91
  231. package/src/v3/message.ts +69 -17
  232. package/src/v3/parameter-store.ts +160 -0
  233. package/src/v3/parameters.ts +110 -37
  234. package/src/v3/protocol.ts +70 -253
  235. package/src/v3/queries.ts +190 -0
  236. package/src/v3/segments.ts +65 -22
  237. package/src/v3/syntax.ts +153 -91
  238. package/dist/session/bank-connection.d.ts +0 -28
  239. package/dist/session/bank-connection.d.ts.map +0 -1
  240. package/dist/session/bank-connection.js +0 -48
  241. package/dist/session/bank-connection.js.map +0 -1
  242. package/dist/session/parameter-data.d.ts +0 -83
  243. package/dist/session/parameter-data.d.ts.map +0 -1
  244. package/dist/session/parameter-data.js +0 -68
  245. package/dist/session/parameter-data.js.map +0 -1
  246. package/dist/session/pin-tan-client.d.ts +0 -54
  247. package/dist/session/pin-tan-client.d.ts.map +0 -1
  248. package/dist/session/pin-tan-client.js +0 -153
  249. package/dist/session/pin-tan-client.js.map +0 -1
  250. package/dist/session/pin-tan-dialog.d.ts +0 -71
  251. package/dist/session/pin-tan-dialog.d.ts.map +0 -1
  252. package/dist/session/pin-tan-dialog.js +0 -124
  253. package/dist/session/pin-tan-dialog.js.map +0 -1
  254. package/dist/session/protocol.d.ts +0 -209
  255. package/dist/session/protocol.d.ts.map +0 -1
  256. package/dist/session/protocol.js +0 -75
  257. package/dist/session/protocol.js.map +0 -1
  258. package/dist/session/response-handler.d.ts +0 -48
  259. package/dist/session/response-handler.d.ts.map +0 -1
  260. package/dist/session/response-handler.js +0 -121
  261. package/dist/session/response-handler.js.map +0 -1
  262. package/dist/v3/client.d.ts +0 -24
  263. package/dist/v3/client.d.ts.map +0 -1
  264. package/dist/v3/client.js +0 -16
  265. package/dist/v3/client.js.map +0 -1
  266. package/src/session/bank-connection.ts +0 -51
  267. package/src/session/parameter-data.ts +0 -137
  268. package/src/session/pin-tan-client.ts +0 -186
  269. package/src/session/pin-tan-dialog.ts +0 -160
  270. package/src/session/protocol.ts +0 -311
  271. package/src/session/response-handler.ts +0 -130
  272. package/src/v3/client.ts +0 -29
@@ -2,11 +2,10 @@ import { Amount } from '../core/amount.js';
2
2
  import { Transaction } from '../core/transaction.js';
3
3
  import { clampedDate, parseSwiftDate } from '../util/dates.js';
4
4
  import { FormatError } from '../util/errors.js';
5
- import { escapeRegExp } from '../util/text.js';
5
+ import { nonBlank } from '../util/text.js';
6
+ import { RecordBudget } from './record-budget.js';
6
7
  import { providedReference, SepaPurpose } from './sepa-purpose.js';
7
8
  const tagPattern = /^:(\d{2}[A-Z]?):/gm;
8
- const statementEnd = /\n-\s*$/;
9
- const trailingNewlines = /\n+$/;
10
9
  /** Parser for SWIFT MT940/MT942 statements, including German structured `:86:` fields. */
11
10
  export const Mt940 = Object.freeze({
12
11
  /** Parses all transactions; see `parse`. */
@@ -14,36 +13,80 @@ export const Mt940 = Object.freeze({
14
13
  return Mt940.parse(text, options).flatMap((s) => [...s.transactions]);
15
14
  },
16
15
  /**
17
- * Parses all statements.
16
+ * Parses all statements. Their lines are separated by line breaks, and by `@@` as well where the first line holds it,
17
+ * as some banks separate them.
18
18
  *
19
- * Throws `FormatError` if a transaction line (`:61:`) cannot be read or the currency of a transaction is unknown.
19
+ * Throws `FormatError` for text without any field, and if a transaction line (`:61:`) or a balance cannot be read or
20
+ * the currency of a transaction is unknown. It does as well for a statement that states only one of its opening and
21
+ * closing balances, one of them, its account or its number twice, or transactions that do not lead from the one
22
+ * balance to the other: a line of a purpose that starts like a field, such as `:61:` or `:25:`, would pass for a
23
+ * transaction, the account or a statement of its own otherwise. Text of more than 200,000 statements and
24
+ * transactions is a `FormatError` as well.
20
25
  */
21
26
  parse(text, options = {}) {
22
- const status = options.status ?? 'booked';
23
- const lines = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
24
- // Some banks separate lines with `@@` instead of line breaks; where there are line breaks, `@@` is text.
25
- const normalized = lines.includes('\n') ? lines : lines.replace(/@@/g, '\n');
26
- const tags = [...normalized.matchAll(tagPattern)];
27
- const statements = [];
28
- let current;
29
- tags.forEach((tag, i) => {
30
- const end = i + 1 < tags.length ? tags[i + 1].index : normalized.length;
31
- const value = normalized
32
- .substring(tag.index + tag[0].length, end)
33
- .replace(statementEnd, '')
34
- .replace(trailingNewlines, '');
35
- if (tag[1] === '20' || current === undefined) {
36
- if (current !== undefined)
37
- statements.push(current.build());
38
- current = new StatementBuilder(status, options.currency);
39
- }
40
- current.add(tag[1], value);
41
- });
42
- if (current !== undefined)
43
- statements.push(current.build());
44
- return statements;
27
+ return parseMt940(text, options, new RecordBudget());
45
28
  },
46
29
  });
30
+ /** `Mt940.parse`, which takes each statement and transaction from `budget`, before it builds it. */
31
+ export function parseMt940(text, options, budget) {
32
+ const status = options.status ?? 'booked';
33
+ const normalized = withLineFeeds(text);
34
+ const statements = [];
35
+ let current;
36
+ for (const [tag, value] of taggedParts(normalized, tagPattern)) {
37
+ if (tag === '20' || current === undefined) {
38
+ if (current !== undefined)
39
+ statements.push(current.build());
40
+ budget.take();
41
+ current = new StatementBuilder(status, options.currency);
42
+ }
43
+ if (tag === '61')
44
+ budget.take();
45
+ current.add(tag, fieldValue(value));
46
+ }
47
+ if (current !== undefined)
48
+ statements.push(current.build());
49
+ else if (normalized.trim() !== '')
50
+ throw new FormatError('MT940 data without fields');
51
+ return statements;
52
+ }
53
+ /**
54
+ * The parts of `text` that the matches of `tag` start, each the first group of its match and the text up to the next
55
+ * match: the fields of a statement, or the subfields of a `:86:`. One by one: text of a few megabytes holds millions of
56
+ * them. A pattern that matched the text up to the next tag as well would run out of backtracking stack on a part of a
57
+ * few million characters.
58
+ */
59
+ function* taggedParts(text, tag) {
60
+ let current;
61
+ let start = 0;
62
+ for (const match of text.matchAll(tag)) {
63
+ if (current !== undefined)
64
+ yield [current, text.substring(start, match.index)];
65
+ current = match[1];
66
+ start = match.index + match[0].length;
67
+ }
68
+ if (current !== undefined)
69
+ yield [current, text.substring(start)];
70
+ }
71
+ /**
72
+ * `text` with line feeds between its lines. Some banks separate them with `@@`, and may still break the line between
73
+ * statements or at the ends. So `@@` separates lines where the first line holds it, which the bank writes; in other
74
+ * text, `@@` may be part of a purpose, which the payer writes.
75
+ */
76
+ function withLineFeeds(text) {
77
+ const lines = text.replace(/\r\n?/g, '\n');
78
+ return lines.trimStart().split('\n', 1)[0].includes('@@') ? lines.replace(/@@/g, '\n') : lines;
79
+ }
80
+ /**
81
+ * The value of a field in `text`, which runs from its tag to the next one: without the blanks and the statement end
82
+ * (`-`) at its end.
83
+ *
84
+ * Trimmed without a pattern such as `/\n+$/`, which takes quadratic time on a long run of line breaks.
85
+ */
86
+ function fieldValue(text) {
87
+ const value = text.trimEnd();
88
+ return value.endsWith('\n-') ? value.substring(0, value.length - 2).trimEnd() : value;
89
+ }
47
90
  const balancePattern = /^([CD])(\d{6})([A-Z]{3})(\d+,\d*)/;
48
91
  const currencyPrefix = /^([A-Z]{3})/;
49
92
  class StatementBuilder {
@@ -75,28 +118,37 @@ class StatementBuilder {
75
118
  this.reference = value.trim();
76
119
  break;
77
120
  case '25':
121
+ if (this.accountId !== undefined)
122
+ throw new FormatError('MT940 statement with two accounts', this.reference);
78
123
  this.accountId = value.trim();
79
124
  break;
80
125
  case '28C':
81
126
  case '28':
127
+ if (this.statementNumber !== undefined) {
128
+ throw new FormatError('MT940 statement with two statement numbers', this.reference);
129
+ }
82
130
  this.statementNumber = value.trim();
83
131
  break;
84
132
  case '60F':
85
133
  case '60M': {
86
- const balance = parseBalance(value);
87
- if (balance) {
88
- [this.opening, this.openingDate] = balance;
89
- this.currency ??= balance[0].currency;
134
+ if (this.opening !== undefined) {
135
+ throw new FormatError('MT940 statement with two opening balances', this.reference);
90
136
  }
137
+ const [balance, date] = parseBalance(value);
138
+ this.opening = balance;
139
+ this.openingDate = date;
140
+ this.currency ??= balance.currency;
91
141
  break;
92
142
  }
93
143
  case '62F':
94
144
  case '62M': {
95
- const balance = parseBalance(value);
96
- if (balance) {
97
- [this.closing, this.closingDate] = balance;
98
- this.currency ??= balance[0].currency;
145
+ if (this.closing !== undefined) {
146
+ throw new FormatError('MT940 statement with two closing balances', this.reference);
99
147
  }
148
+ const [balance, date] = parseBalance(value);
149
+ this.closing = balance;
150
+ this.closingDate = date;
151
+ this.currency ??= balance.currency;
100
152
  break;
101
153
  }
102
154
  case '34F':
@@ -117,6 +169,10 @@ class StatementBuilder {
117
169
  if (statementCurrency === undefined && this.transactions.length > 0) {
118
170
  throw new FormatError('MT940 statement without currency', this.reference);
119
171
  }
172
+ const { openingDate, closingDate } = this;
173
+ const period = openingDate && closingDate ? [openingDate, closingDate] : undefined;
174
+ const transactions = this.transactions.map((t) => t.toTransaction(statementCurrency, this.status, period));
175
+ this.checkBalances(transactions);
120
176
  return Object.freeze({
121
177
  reference: this.reference,
122
178
  accountId: this.accountId,
@@ -126,14 +182,40 @@ class StatementBuilder {
126
182
  openingDate: this.openingDate,
127
183
  closingBalance: this.closing,
128
184
  closingDate: this.closingDate,
129
- transactions: Object.freeze(this.transactions.map((t) => t.toTransaction(statementCurrency, this.status))),
185
+ transactions: Object.freeze(transactions),
130
186
  });
131
187
  }
188
+ /** Checks that the statement states both balances or neither, and that its `transactions` lead from one to the other. */
189
+ checkBalances(transactions) {
190
+ const { opening, closing } = this;
191
+ if (opening === undefined && closing === undefined)
192
+ return;
193
+ if (opening === undefined || closing === undefined) {
194
+ throw new FormatError('MT940 statement with only one of its balances', this.reference);
195
+ }
196
+ if (opening.currency !== this.currency || closing.currency !== this.currency) {
197
+ throw new FormatError('MT940 balances in another currency than the statement', this.reference);
198
+ }
199
+ if (!balanceAfter(opening, transactions).equals(closing)) {
200
+ throw new FormatError('MT940 transactions do not add up to the closing balance', this.reference);
201
+ }
202
+ }
203
+ }
204
+ /** `opening` plus the amounts of `transactions`; throws `FormatError` for a sum beyond what an `Amount` holds. */
205
+ function balanceAfter(opening, transactions) {
206
+ try {
207
+ return transactions.reduce((balance, t) => balance.add(t.amount), opening);
208
+ }
209
+ catch (error) {
210
+ if (error instanceof RangeError)
211
+ throw new FormatError('MT940 amounts too large to add up');
212
+ throw error;
213
+ }
132
214
  }
133
215
  function parseBalance(value) {
134
216
  const m = balancePattern.exec(value.trim());
135
217
  if (!m)
136
- return undefined;
218
+ throw new FormatError('Unreadable MT940 balance', value);
137
219
  const amount = Amount.parseDecimal(m[4], m[3]);
138
220
  const date = parseSwiftDate(m[2]);
139
221
  if (date === undefined)
@@ -152,7 +234,7 @@ class TransactionLines {
152
234
  constructor(line) {
153
235
  this.line = line;
154
236
  }
155
- toTransaction(currency, status) {
237
+ toTransaction(currency, status, period) {
156
238
  const m = line61.exec(this.line.trim());
157
239
  const valueDate = m ? parseSwiftDate(m[1]) : undefined;
158
240
  if (!m || valueDate === undefined)
@@ -160,20 +242,17 @@ class TransactionLines {
160
242
  const mark = m[3];
161
243
  const amount = Amount.parseDecimal(m[5], currency);
162
244
  const debit = mark === 'D' || mark === 'RC';
163
- const customerReference = m[7]?.trim();
164
- const bankReference = m[8]?.trim();
245
+ const customerReference = nonBlank(m[7]);
165
246
  const d = Details.parse(this.details);
166
247
  return new Transaction({
167
248
  status,
168
- bookingDate: this.bookingDate(m[2], valueDate),
249
+ bookingDate: this.bookingDate(m[2], valueDate, period),
169
250
  valueDate,
170
251
  amount: debit ? amount.negate() : amount,
171
252
  isReversal: mark.startsWith('R'),
172
253
  transactionTypeId: m[6],
173
- customerReference: customerReference === undefined || customerReference === '' || customerReference === 'NONREF'
174
- ? undefined
175
- : customerReference,
176
- bankReference: bankReference === undefined || bankReference === '' ? undefined : bankReference,
254
+ customerReference: customerReference === 'NONREF' ? undefined : customerReference,
255
+ bankReference: nonBlank(m[8]),
177
256
  transactionCode: d.transactionCode,
178
257
  bookingText: d.bookingText,
179
258
  primaNota: d.primaNota,
@@ -191,35 +270,41 @@ class TransactionLines {
191
270
  purposeCodes: d.sepa,
192
271
  });
193
272
  }
194
- /** The booking date `MMDD`, in the year that places it closest to `valueDate` (across a year end). */
195
- bookingDate(mmdd, valueDate) {
273
+ /**
274
+ * The booking date `MMDD`, in the year that places it within `period`, or else closest to it; of several such years,
275
+ * the one closest to `valueDate`; without a period, the year closest to `valueDate`. The value date alone misleads:
276
+ * banks book refunds and corrections with the value date of the original booking, up to 13 months before.
277
+ */
278
+ bookingDate(mmdd, valueDate, period) {
196
279
  if (mmdd === undefined)
197
280
  return undefined;
198
281
  const month = Number(mmdd.substring(0, 2));
199
282
  const day = Number(mmdd.substring(2, 4));
200
- let year = valueDate.getFullYear();
201
- if (month === 12 && valueDate.getMonth() === 0)
202
- year--;
203
- if (month === 1 && valueDate.getMonth() === 11)
204
- year++;
205
- const date = clampedDate(year, month, day);
206
- if (date === undefined)
207
- throw new FormatError('Invalid booking date', this.line);
208
- return date;
283
+ const [first, last] = period ?? [valueDate, valueDate];
284
+ const outside = (date) => Math.max(first.getTime() - date.getTime(), date.getTime() - last.getTime(), 0);
285
+ const fromValueDate = (date) => Math.abs(date.getTime() - valueDate.getTime());
286
+ // The best year lies next to one of these, however long the period.
287
+ const years = new Set([first, valueDate, last].flatMap((d) => [d.getFullYear() - 1, d.getFullYear(), d.getFullYear() + 1]));
288
+ let best;
289
+ for (const year of years) {
290
+ const date = clampedDate(year, month, day);
291
+ if (date === undefined)
292
+ throw new FormatError('Invalid booking date', this.line);
293
+ if (best === undefined || (outside(date) - outside(best) || fromValueDate(date) - fromValueDate(best)) < 0) {
294
+ best = date;
295
+ }
296
+ }
297
+ return best;
209
298
  }
210
299
  }
211
300
  /**
212
- * Three-digit business transaction code (GVC), then the first subfield: a separator, usually `?`, and its two-digit
213
- * number. Text that merely starts with three digits, such as `100 Euro`, is free text.
301
+ * Three-digit business transaction code (GVC), then the first subfield: `?` and its two-digit number. Text that merely
302
+ * starts with three digits, such as `100 Euro` or `100,00 EUR`, is free text.
214
303
  */
215
- const structuredPattern = /^(\d{3})([^\w\s])\d{2}/;
304
+ const structuredPattern = /^\d{3}\?\d{2}/;
305
+ const subfieldTag = /\?(\d{2})/g;
216
306
  const ibanPattern = /^[A-Z]{2}\d{2}[A-Z0-9]+$/;
217
307
  const bicPattern = /^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/;
218
- /** Subfield pattern for a separator: the separator, a two-digit key, then everything up to the next subfield. */
219
- function subfieldPattern(separator) {
220
- const s = escapeRegExp(separator);
221
- return new RegExp(`${s}(\\d{2})((?:(?!${s}\\d{2})[\\s\\S])*)`, 'g');
222
- }
223
308
  /** The German structured `:86:` field: a business transaction code and `?nn` subfields. */
224
309
  class Details {
225
310
  transactionCode;
@@ -237,41 +322,35 @@ class Details {
237
322
  if (raw === undefined)
238
323
  return d;
239
324
  const text = raw.replace(/\n/g, '');
240
- const structured = structuredPattern.exec(text);
241
- if (!structured) {
325
+ if (!structuredPattern.test(text)) {
242
326
  // Free text, whose lines are separate phrases; the purpose and its keywords are read from the same text.
243
327
  const free = raw.replace(/\n/g, ' ').trim();
244
328
  d.sepa = SepaPurpose.parse(free);
245
- d.purpose = d.sepa.get('SVWZ') ?? (free === '' ? undefined : free);
329
+ d.purpose = d.sepa.get('SVWZ') ?? nonBlank(free);
246
330
  return d;
247
331
  }
248
- d.transactionCode = structured[1];
249
- const subfields = Details.subfields(text.substring(3), structured[2]);
250
- const subfield = (key) => {
251
- const value = subfields.get(key)?.trim();
252
- return value === undefined || value === '' ? undefined : value;
253
- };
332
+ d.transactionCode = text.substring(0, 3);
333
+ const subfields = Details.subfields(text.substring(3));
334
+ const subfield = (key) => nonBlank(subfields.get(key));
254
335
  // Subfields continue each other: they are joined keeping the spaces at their boundaries.
255
336
  const parts = (keys) => keys.map((k) => subfields.get(k)).filter((v) => v !== undefined);
256
337
  d.bookingText = subfield(0);
257
338
  d.primaNota = subfield(10);
258
339
  const purposeParts = parts([20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 60, 61, 62, 63]);
259
- const purpose = purposeParts.join('').trim();
260
340
  d.sepa = SepaPurpose.parseParts(purposeParts);
261
- d.purpose = d.sepa.get('SVWZ') ?? (purpose === '' ? undefined : purpose);
262
- const name = parts([32, 33]).join('').trim();
263
- d.name = name === '' ? undefined : name;
341
+ d.purpose = d.sepa.get('SVWZ') ?? nonBlank(purposeParts.join(''));
342
+ d.name = nonBlank(parts([32, 33]).join(''));
264
343
  d.readCounterpartyAccount(subfield(30), subfield(31));
265
344
  d.iban ??= d.sepa.get('IBAN');
266
345
  d.bic ??= d.sepa.get('BIC');
267
346
  return d;
268
347
  }
269
348
  /** The text of each subfield (`?nn` and what follows), by its number; a subfield that appears twice is joined. */
270
- static subfields(text, separator) {
349
+ static subfields(text) {
271
350
  const subfields = new Map();
272
- for (const m of text.matchAll(subfieldPattern(separator))) {
273
- const key = Number(m[1]);
274
- subfields.set(key, (subfields.get(key) ?? '') + m[2]);
351
+ for (const [tag, value] of taggedParts(text, subfieldTag)) {
352
+ const key = Number(tag);
353
+ subfields.set(key, (subfields.get(key) ?? '') + value);
275
354
  }
276
355
  return subfields;
277
356
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mt940.js","sourceRoot":"","sources":["../../src/formats/mt940.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mt940.js","sourceRoot":"","sources":["../../src/formats/mt940.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAA0B,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAmCnE,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC,0FAA0F;AAC1F,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,4CAA4C;IAC5C,iBAAiB,CAAC,IAAY,EAAE,UAAwB,EAAE;QACxD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,IAAY,EAAE,UAAwB,EAAE;QAC5C,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,YAAY,EAAE,CAAC,CAAC;IACvD,CAAC;CACF,CAAC,CAAC;AAEH,oGAAoG;AACpG,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,OAAqB,EAAE,MAAoB;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC;IAC1C,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,IAAI,OAAqC,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;QAC/D,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1C,IAAI,OAAO,KAAK,SAAS;gBAAE,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YAC5D,MAAM,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,GAAG,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,KAAK,SAAS;QAAE,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;SACvD,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,WAAW,CAAC,2BAA2B,CAAC,CAAC;IACtF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,QAAQ,CAAC,CAAC,WAAW,CAAC,IAAY,EAAE,GAAW;IAC7C,IAAI,OAA2B,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/E,OAAO,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACpB,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAClG,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AACxF,CAAC;AAED,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAC3D,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC,MAAM,gBAAgB;IAkBD;IAEA;IAnBnB,SAAS,CAAqB;IAC9B,SAAS,CAAqB;IAC9B,eAAe,CAAqB;IACpC,QAAQ,CAAqB;IAC7B,OAAO,CAAqB;IAC5B,WAAW,CAAmB;IAC9B,OAAO,CAAqB;IAC5B,WAAW,CAAmB;IACrB,YAAY,GAAuB,EAAE,CAAC;IAE/C;;;OAGG;IACK,WAAW,CAAqB;IAExC,YACmB,MAAyB;IAC1C,sDAAsD;IACrC,gBAAoC;QAFpC,WAAM,GAAN,MAAM,CAAmB;QAEzB,qBAAgB,GAAhB,gBAAgB,CAAoB;IACpD,CAAC;IAEJ,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,IAAI;gBACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC9B,MAAM;YACR,KAAK,IAAI;gBACP,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;oBAAE,MAAM,IAAI,WAAW,CAAC,mCAAmC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7G,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC9B,MAAM;YACR,KAAK,KAAK,CAAC;YACX,KAAK,IAAI;gBACP,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;oBACvC,MAAM,IAAI,WAAW,CAAC,4CAA4C,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtF,CAAC;gBACD,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;gBACpC,MAAM;YACR,KAAK,KAAK,CAAC;YACX,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC/B,MAAM,IAAI,WAAW,CAAC,2CAA2C,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBACrF,CAAC;gBACD,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC;gBACnC,MAAM;YACR,CAAC;YACD,KAAK,KAAK,CAAC;YACX,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC/B,MAAM,IAAI,WAAW,CAAC,2CAA2C,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBACrF,CAAC;gBACD,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC;gBACnC,MAAM;YACR,CAAC;YACD,KAAK,KAAK;gBACR,IAAI,CAAC,QAAQ,KAAK,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACzD,MAAM;YACR,KAAK,IAAI;gBACP,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;gBACpD,MAAM;YACR,KAAK,IAAI;gBACP,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;oBAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,GAAG,KAAK,CAAC;gBACzE,MAAM;QACV,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IACzB,CAAC;IAED,KAAK;QACH,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,CAAC;QACjE,IAAI,iBAAiB,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,WAAW,CAAC,kCAAkC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;QAC1C,MAAM,MAAM,GAAG,WAAW,IAAI,WAAW,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,WAAW,CAAW,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9F,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,iBAAkB,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5G,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,QAAQ,EAAE,iBAAiB;YAC3B,cAAc,EAAE,IAAI,CAAC,OAAO;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,cAAc,EAAE,IAAI,CAAC,OAAO;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,yHAAyH;IACjH,aAAa,CAAC,YAAoC;QACxD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAClC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QAC3D,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACnD,MAAM,IAAI,WAAW,CAAC,+CAA+C,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7E,MAAM,IAAI,WAAW,CAAC,uDAAuD,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACjG,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,WAAW,CAAC,yDAAyD,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACnG,CAAC;IACH,CAAC;CACF;AAED,kHAAkH;AAClH,SAAS,YAAY,CAAC,OAAe,EAAE,YAAoC;IACzE,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,UAAU;YAAE,MAAM,IAAI,WAAW,CAAC,mCAAmC,CAAC,CAAC;QAC5F,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IACnC,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC7E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,MAAM,GACV,2GAA2G,CAAC;AAK9G,+DAA+D;AAC/D,MAAM,gBAAgB;IAGC;IAFrB,OAAO,CAAqB;IAE5B,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAErC,aAAa,CAAC,QAAgB,EAAE,MAAyB,EAAE,MAA0B;QACnF,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACxD,IAAI,CAAC,CAAC,IAAI,SAAS,KAAK,SAAS;YAAE,MAAM,IAAI,WAAW,CAAC,0CAA0C,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChH,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACnB,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC;QAC5C,MAAM,iBAAiB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,IAAI,WAAW,CAAC;YACrB,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC;YACtD,SAAS;YACT,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM;YACxC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAChC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,iBAAiB,EAAE,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB;YACjF,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,eAAe,EAAE,CAAC,CAAC,eAAe;YAClC,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,gBAAgB,EAAE,CAAC,CAAC,IAAI;YACxB,gBAAgB,EAAE,CAAC,CAAC,IAAI;YACxB,eAAe,EAAE,CAAC,CAAC,GAAG;YACtB,yBAAyB,EAAE,CAAC,CAAC,aAAa;YAC1C,oBAAoB,EAAE,CAAC,CAAC,QAAQ;YAChC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjD,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAC7B,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAC9B,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YACpC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAClC,YAAY,EAAE,CAAC,CAAC,IAAI;SACrB,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,WAAW,CAAC,IAAwB,EAAE,SAAe,EAAE,MAA0B;QACvF,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,CAAC,IAAU,EAAU,EAAE,CACrC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QACjF,MAAM,aAAa,GAAG,CAAC,IAAU,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7F,oEAAoE;QACpE,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,CACrG,CAAC;QACF,IAAI,IAAsB,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;YAC3C,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACjF,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3G,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAC1C,MAAM,WAAW,GAAG,YAAY,CAAC;AACjC,MAAM,WAAW,GAAG,0BAA0B,CAAC;AAC/C,MAAM,UAAU,GAAG,qCAAqC,CAAC;AAEzD,2FAA2F;AAC3F,MAAM,OAAO;IACX,eAAe,CAAqB;IACpC,WAAW,CAAqB;IAChC,SAAS,CAAqB;IAC9B,OAAO,CAAqB;IAC5B,IAAI,CAAqB;IACzB,IAAI,CAAqB;IACzB,GAAG,CAAqB;IACxB,aAAa,CAAqB;IAClC,QAAQ,CAAqB;IAC7B,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEjC,MAAM,CAAC,KAAK,CAAC,GAAuB;QAClC,MAAM,CAAC,GAAG,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,yGAAyG;YACzG,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAsB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,yFAAyF;QACzF,MAAM,KAAK,GAAG,CAAC,IAAc,EAAY,EAAE,CACzC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;QAEhF,CAAC,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACrF,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAClE,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,kHAAkH;IAC1G,MAAM,CAAC,SAAS,CAAC,IAAY;QACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;YAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;OAGG;IACK,uBAAuB,CAAC,IAAwB,EAAE,OAA2B;QACnF,IAAI,OAAO,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;YACpB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;YAChB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;IACH,CAAC;CACF"}
@@ -3,9 +3,13 @@ import type { Transaction } from '../core/transaction.js';
3
3
  * The transactions in MT940 data: the `booked` parts joined, since a statement may continue on the next page, then the
4
4
  * `pending` ones (MT942).
5
5
  *
6
- * `currency` applies to statements that do not state one; throws `FormatError` if both are missing.
6
+ * `currency` applies to statements that do not state one; throws `FormatError` if both are missing, and for more than
7
+ * 200,000 statements and transactions in all.
7
8
  */
8
9
  export declare function mt940Transactions(booked: readonly Uint8Array[], pending: readonly Uint8Array[], currency: string | undefined): Transaction[];
9
- /** The transactions in camt documents; each document stands on its own. */
10
+ /**
11
+ * The transactions in camt documents; each document stands on its own. Throws `FormatError` for more than 200,000
12
+ * statements and transactions in all.
13
+ */
10
14
  export declare function camtTransactions(booked: readonly Uint8Array[], pending: readonly Uint8Array[]): Transaction[];
11
15
  //# sourceMappingURL=readers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readers.d.ts","sourceRoot":"","sources":["../../src/formats/readers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,WAAW,EAAE,CAKf;AA4BD,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAK7G"}
1
+ {"version":3,"file":"readers.d.ts","sourceRoot":"","sources":["../../src/formats/readers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1D;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,WAAW,EAAE,CAMf;AAeD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,CAM7G"}
@@ -1,47 +1,42 @@
1
- import { BytesBuilder } from '../util/bytes.js';
2
1
  import { decodeBankText, decodeXmlText } from '../util/text.js';
3
- import { Camt } from './camt.js';
4
- import { Mt940 } from './mt940.js';
2
+ import { parseCamt } from './camt.js';
3
+ import { parseMt940 } from './mt940.js';
4
+ import { RecordBudget } from './record-budget.js';
5
5
  /**
6
6
  * The transactions in MT940 data: the `booked` parts joined, since a statement may continue on the next page, then the
7
7
  * `pending` ones (MT942).
8
8
  *
9
- * `currency` applies to statements that do not state one; throws `FormatError` if both are missing.
9
+ * `currency` applies to statements that do not state one; throws `FormatError` if both are missing, and for more than
10
+ * 200,000 statements and transactions in all.
10
11
  */
11
12
  export function mt940Transactions(booked, pending, currency) {
13
+ const budget = new RecordBudget();
12
14
  return [
13
- ...Mt940.parseTransactions(joinedMt940(booked), { currency }),
14
- ...Mt940.parseTransactions(joinedMt940(pending), { currency, status: 'pending' }),
15
- ];
15
+ ...parseMt940(joinedMt940(booked), { currency }, budget),
16
+ ...parseMt940(joinedMt940(pending), { currency, status: 'pending' }, budget),
17
+ ].flatMap((statement) => statement.transactions);
16
18
  }
17
- const lineFeed = 0x0a;
18
- const carriageReturn = 0x0d;
19
- const atSign = 0x40;
20
19
  /**
21
- * The MT940 `parts` as one text.
20
+ * The MT940 `parts` as one text, whose line separator the parser takes from its first line: a later page may start
21
+ * with a purpose, which the payer writes.
22
22
  *
23
- * Each part ends a line before the next one follows, since the parser finds fields at the start of a line and a bank
24
- * need not end its pages with a line break. Banks that separate lines with `@@` get that separator.
23
+ * Each part is decoded on its own, since a bank may start each page with a byte order mark. Each part ends a line
24
+ * before the next one follows, since the parser finds fields at the start of a line and a bank need not end its pages
25
+ * with a line break.
25
26
  */
26
27
  function joinedMt940(parts) {
27
- const pages = parts.filter((part) => part.length > 0);
28
- const atSigns = !pages.some((p) => p.includes(lineFeed) || p.includes(carriageReturn));
29
- const endsLine = (page) => atSigns
30
- ? page.length >= 2 && page[page.length - 1] === atSign && page[page.length - 2] === atSign
31
- : page.at(-1) === lineFeed || page.at(-1) === carriageReturn;
32
- const bytes = new BytesBuilder();
33
- pages.forEach((page, i) => {
34
- if (i > 0 && !endsLine(pages[i - 1]))
35
- bytes.add(atSigns ? [atSign, atSign] : [lineFeed]);
36
- bytes.add(page);
37
- });
38
- return decodeBankText(bytes.takeBytes());
28
+ const pages = parts.filter((part) => part.length > 0).map((part) => decodeBankText(part));
29
+ return pages.map((page, i) => (i + 1 < pages.length && !page.endsWith('\n') ? `${page}\n` : page)).join('');
39
30
  }
40
- /** The transactions in camt documents; each document stands on its own. */
31
+ /**
32
+ * The transactions in camt documents; each document stands on its own. Throws `FormatError` for more than 200,000
33
+ * statements and transactions in all.
34
+ */
41
35
  export function camtTransactions(booked, pending) {
36
+ const budget = new RecordBudget();
42
37
  return [
43
- ...booked.flatMap((document) => Camt.parseTransactions(decodeXmlText(document))),
44
- ...pending.flatMap((document) => Camt.parseTransactions(decodeXmlText(document), 'pending')),
45
- ];
38
+ ...booked.flatMap((document) => parseCamt(decodeXmlText(document), undefined, budget)),
39
+ ...pending.flatMap((document) => parseCamt(decodeXmlText(document), 'pending', budget)),
40
+ ].flatMap((statement) => statement.transactions);
46
41
  }
47
42
  //# sourceMappingURL=readers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"readers.js","sourceRoot":"","sources":["../../src/formats/readers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA6B,EAC7B,OAA8B,EAC9B,QAA4B;IAE5B,OAAO;QACL,GAAG,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;QAC7D,GAAG,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;KAClF,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtB,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,MAAM,GAAG,IAAI,CAAC;AAEpB;;;;;GAKG;AACH,SAAS,WAAW,CAAC,KAA4B;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;IACvF,MAAM,QAAQ,GAAG,CAAC,IAAgB,EAAW,EAAE,CAC7C,OAAO;QACL,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM;QAC1F,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC;IAEjE,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IACjC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1F,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,gBAAgB,CAAC,MAA6B,EAAE,OAA8B;IAC5F,OAAO;QACL,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChF,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;KAC7F,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"readers.js","sourceRoot":"","sources":["../../src/formats/readers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA6B,EAC7B,OAA8B,EAC9B,QAA4B;IAE5B,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,OAAO;QACL,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC;QACxD,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;KAC7E,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,KAA4B;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1F,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9G,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA6B,EAAE,OAA8B;IAC5F,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,OAAO;QACL,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACtF,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;KACxF,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** The statements and transactions the parsers may still build; the parses of one query share one budget. */
2
+ export declare class RecordBudget {
3
+ private left;
4
+ /** Counts a statement or transaction about to be built; throws `FormatError` for one beyond the budget. */
5
+ take(): void;
6
+ }
7
+ //# sourceMappingURL=record-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-budget.d.ts","sourceRoot":"","sources":["../../src/formats/record-budget.ts"],"names":[],"mappings":"AASA,6GAA6G;AAC7G,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAc;IAE1B,2GAA2G;IAC3G,IAAI,IAAI,IAAI;CAGb"}
@@ -0,0 +1,17 @@
1
+ import { FormatError } from '../util/errors.js';
2
+ /**
3
+ * Most statements and transactions the parsers build for one query: several times what a year of a busy business
4
+ * account holds, and few enough that a hostile answer cannot exhaust the memory, at about 600 bytes each. The size of
5
+ * the answer does not bound them: a transaction takes up to 25 times the bytes of its MT940 line.
6
+ */
7
+ const maxRecords = 200_000;
8
+ /** The statements and transactions the parsers may still build; the parses of one query share one budget. */
9
+ export class RecordBudget {
10
+ left = maxRecords;
11
+ /** Counts a statement or transaction about to be built; throws `FormatError` for one beyond the budget. */
12
+ take() {
13
+ if (--this.left < 0)
14
+ throw new FormatError(`More than ${maxRecords} statements and transactions`);
15
+ }
16
+ }
17
+ //# sourceMappingURL=record-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-budget.js","sourceRoot":"","sources":["../../src/formats/record-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,GAAG,OAAO,CAAC;AAE3B,6GAA6G;AAC7G,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,UAAU,CAAC;IAE1B,2GAA2G;IAC3G,IAAI;QACF,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,aAAa,UAAU,8BAA8B,CAAC,CAAC;IACpG,CAAC;CACF"}
@@ -8,6 +8,12 @@ export declare const SepaPurpose: Readonly<{
8
8
  * A keyword counts unless a capital letter comes right before it, so `XEREF+` does not open an EREF value. After a
9
9
  * digit or a small letter it does: a purpose line cut at 35 characters is joined to the next one without a space, so
10
10
  * `…4711EREF+` may be where one line ends and the next begins.
11
+ *
12
+ * The remittance information (`SVWZ+`) and the ultimate debtor and creditor (`ABWA+`, `ABWE+`) are text the payer or
13
+ * the payee writes, which banks put after every other keyword. So from the first of them on only `ABWA+` and `ABWE+`
14
+ * start a value: a keyword in that text, such as `IBAN+`, is part of it. A keyword that occurs twice has no value:
15
+ * which of the two the bank wrote cannot be told, since a reference the payee chose, such as `EREF+`, comes before
16
+ * the bank's `CRED+` and may hold `CRED+…` and `SVWZ+`, which turns the bank's value into remittance information.
11
17
  */
12
18
  parse(purpose: string): Map<string, string>;
13
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sepa-purpose.d.ts","sourceRoot":"","sources":["../../src/formats/sepa-purpose.ts"],"names":[],"mappings":"AAqBA,yGAAyG;AACzG,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEnF;AAID,sDAAsD;AACtD,eAAO,MAAM,WAAW;IACtB;;;;;;OAMG;mBACY,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAI3C;;;;;;OAMG;sBACe,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;EASxD,CAAC"}
1
+ {"version":3,"file":"sepa-purpose.d.ts","sourceRoot":"","sources":["../../src/formats/sepa-purpose.ts"],"names":[],"mappings":"AAqBA,yGAAyG;AACzG,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEnF;AAOD,sDAAsD;AACtD,eAAO,MAAM,WAAW;IACtB;;;;;;;;;;;;OAYG;mBACY,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAI3C;;;;;;OAMG;sBACe,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;EASxD,CAAC"}