@coderoftime/fints 0.2.0 → 0.3.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 (215) hide show
  1. package/CHANGELOG.md +377 -0
  2. package/README.md +31 -23
  3. package/dist/client.d.ts +3 -2
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +52 -9
  6. package/dist/client.js.map +1 -1
  7. package/dist/core/account.d.ts +15 -4
  8. package/dist/core/account.d.ts.map +1 -1
  9. package/dist/core/account.js +84 -36
  10. package/dist/core/account.js.map +1 -1
  11. package/dist/core/amount.d.ts +13 -3
  12. package/dist/core/amount.d.ts.map +1 -1
  13. package/dist/core/amount.js +42 -8
  14. package/dist/core/amount.js.map +1 -1
  15. package/dist/core/balance.d.ts +3 -0
  16. package/dist/core/balance.d.ts.map +1 -1
  17. package/dist/core/balance.js +5 -0
  18. package/dist/core/balance.js.map +1 -1
  19. package/dist/core/bank-info.d.ts +20 -3
  20. package/dist/core/bank-info.d.ts.map +1 -1
  21. package/dist/core/bank-info.js +25 -4
  22. package/dist/core/bank-info.js.map +1 -1
  23. package/dist/core/client.d.ts +42 -15
  24. package/dist/core/client.d.ts.map +1 -1
  25. package/dist/core/config.d.ts +15 -7
  26. package/dist/core/config.d.ts.map +1 -1
  27. package/dist/core/config.js +29 -14
  28. package/dist/core/config.js.map +1 -1
  29. package/dist/core/errors.d.ts +17 -5
  30. package/dist/core/errors.d.ts.map +1 -1
  31. package/dist/core/errors.js +25 -7
  32. package/dist/core/errors.js.map +1 -1
  33. package/dist/core/feedback.d.ts +7 -0
  34. package/dist/core/feedback.d.ts.map +1 -1
  35. package/dist/core/feedback.js +10 -1
  36. package/dist/core/feedback.js.map +1 -1
  37. package/dist/core/transaction.d.ts +5 -0
  38. package/dist/core/transaction.d.ts.map +1 -1
  39. package/dist/core/transaction.js +12 -0
  40. package/dist/core/transaction.js.map +1 -1
  41. package/dist/core/transport.d.ts +22 -7
  42. package/dist/core/transport.d.ts.map +1 -1
  43. package/dist/core/transport.js +51 -11
  44. package/dist/core/transport.js.map +1 -1
  45. package/dist/formats/camt.d.ts +7 -4
  46. package/dist/formats/camt.d.ts.map +1 -1
  47. package/dist/formats/camt.js +53 -54
  48. package/dist/formats/camt.js.map +1 -1
  49. package/dist/formats/mt940.d.ts +18 -6
  50. package/dist/formats/mt940.d.ts.map +1 -1
  51. package/dist/formats/mt940.js +83 -66
  52. package/dist/formats/mt940.js.map +1 -1
  53. package/dist/formats/readers.d.ts.map +1 -1
  54. package/dist/formats/readers.js +6 -2
  55. package/dist/formats/readers.js.map +1 -1
  56. package/dist/formats/sepa-purpose.d.ts +7 -4
  57. package/dist/formats/sepa-purpose.d.ts.map +1 -1
  58. package/dist/formats/sepa-purpose.js +18 -9
  59. package/dist/formats/sepa-purpose.js.map +1 -1
  60. package/dist/session/dialog-runner.d.ts +5 -2
  61. package/dist/session/dialog-runner.d.ts.map +1 -1
  62. package/dist/session/dialog-runner.js +23 -7
  63. package/dist/session/dialog-runner.js.map +1 -1
  64. package/dist/session/login-guard.d.ts +4 -4
  65. package/dist/session/login-guard.d.ts.map +1 -1
  66. package/dist/session/login-guard.js +29 -14
  67. package/dist/session/login-guard.js.map +1 -1
  68. package/dist/session/session-setup.d.ts +14 -5
  69. package/dist/session/session-setup.d.ts.map +1 -1
  70. package/dist/session/session-setup.js +30 -9
  71. package/dist/session/session-setup.js.map +1 -1
  72. package/dist/session/session-state.d.ts +4 -3
  73. package/dist/session/session-state.d.ts.map +1 -1
  74. package/dist/session/session-state.js +28 -9
  75. package/dist/session/session-state.js.map +1 -1
  76. package/dist/session/signed-dialog.d.ts +19 -13
  77. package/dist/session/signed-dialog.d.ts.map +1 -1
  78. package/dist/session/signed-dialog.js +45 -30
  79. package/dist/session/signed-dialog.js.map +1 -1
  80. package/dist/session/user-prompts.d.ts +6 -1
  81. package/dist/session/user-prompts.d.ts.map +1 -1
  82. package/dist/session/user-prompts.js +19 -4
  83. package/dist/session/user-prompts.js.map +1 -1
  84. package/dist/tan/challenge.d.ts +15 -13
  85. package/dist/tan/challenge.d.ts.map +1 -1
  86. package/dist/tan/challenge.js +32 -26
  87. package/dist/tan/challenge.js.map +1 -1
  88. package/dist/tan/flicker.d.ts +5 -1
  89. package/dist/tan/flicker.d.ts.map +1 -1
  90. package/dist/tan/flicker.js +42 -30
  91. package/dist/tan/flicker.js.map +1 -1
  92. package/dist/tan/tan-image.d.ts +4 -1
  93. package/dist/tan/tan-image.d.ts.map +1 -1
  94. package/dist/tan/tan-image.js +8 -2
  95. package/dist/tan/tan-image.js.map +1 -1
  96. package/dist/tan/tan-models.d.ts +9 -1
  97. package/dist/tan/tan-models.d.ts.map +1 -1
  98. package/dist/tan/tan-models.js +14 -2
  99. package/dist/tan/tan-models.js.map +1 -1
  100. package/dist/util/arguments.d.ts +13 -0
  101. package/dist/util/arguments.d.ts.map +1 -0
  102. package/dist/util/arguments.js +40 -0
  103. package/dist/util/arguments.js.map +1 -0
  104. package/dist/util/async.d.ts +4 -1
  105. package/dist/util/async.d.ts.map +1 -1
  106. package/dist/util/async.js +6 -3
  107. package/dist/util/async.js.map +1 -1
  108. package/dist/util/bytes.d.ts +1 -1
  109. package/dist/util/bytes.d.ts.map +1 -1
  110. package/dist/util/bytes.js +3 -3
  111. package/dist/util/bytes.js.map +1 -1
  112. package/dist/util/dates.d.ts +3 -10
  113. package/dist/util/dates.d.ts.map +1 -1
  114. package/dist/util/dates.js +49 -39
  115. package/dist/util/dates.js.map +1 -1
  116. package/dist/util/errors.d.ts +5 -3
  117. package/dist/util/errors.d.ts.map +1 -1
  118. package/dist/util/errors.js +8 -4
  119. package/dist/util/errors.js.map +1 -1
  120. package/dist/util/immutable-map.d.ts +5 -2
  121. package/dist/util/immutable-map.d.ts.map +1 -1
  122. package/dist/util/immutable-map.js +15 -12
  123. package/dist/util/immutable-map.js.map +1 -1
  124. package/dist/util/inspect.d.ts +11 -0
  125. package/dist/util/inspect.d.ts.map +1 -0
  126. package/dist/util/inspect.js +14 -0
  127. package/dist/util/inspect.js.map +1 -0
  128. package/dist/util/text.d.ts +18 -2
  129. package/dist/util/text.d.ts.map +1 -1
  130. package/dist/util/text.js +50 -5
  131. package/dist/util/text.js.map +1 -1
  132. package/dist/util/xml.d.ts +6 -4
  133. package/dist/util/xml.d.ts.map +1 -1
  134. package/dist/util/xml.js +106 -44
  135. package/dist/util/xml.js.map +1 -1
  136. package/dist/v3/bank-connection.d.ts +23 -3
  137. package/dist/v3/bank-connection.d.ts.map +1 -1
  138. package/dist/v3/bank-connection.js +66 -6
  139. package/dist/v3/bank-connection.js.map +1 -1
  140. package/dist/v3/dialog.d.ts +6 -2
  141. package/dist/v3/dialog.d.ts.map +1 -1
  142. package/dist/v3/dialog.js +20 -9
  143. package/dist/v3/dialog.js.map +1 -1
  144. package/dist/v3/message.d.ts +18 -10
  145. package/dist/v3/message.d.ts.map +1 -1
  146. package/dist/v3/message.js +92 -75
  147. package/dist/v3/message.js.map +1 -1
  148. package/dist/v3/parameter-store.d.ts +43 -7
  149. package/dist/v3/parameter-store.d.ts.map +1 -1
  150. package/dist/v3/parameter-store.js +69 -15
  151. package/dist/v3/parameter-store.js.map +1 -1
  152. package/dist/v3/parameters.d.ts +12 -11
  153. package/dist/v3/parameters.d.ts.map +1 -1
  154. package/dist/v3/parameters.js +57 -35
  155. package/dist/v3/parameters.js.map +1 -1
  156. package/dist/v3/protocol.d.ts +16 -9
  157. package/dist/v3/protocol.d.ts.map +1 -1
  158. package/dist/v3/protocol.js +57 -26
  159. package/dist/v3/protocol.js.map +1 -1
  160. package/dist/v3/queries.d.ts +2 -2
  161. package/dist/v3/queries.d.ts.map +1 -1
  162. package/dist/v3/queries.js +24 -16
  163. package/dist/v3/queries.js.map +1 -1
  164. package/dist/v3/segments.d.ts +18 -11
  165. package/dist/v3/segments.d.ts.map +1 -1
  166. package/dist/v3/segments.js +30 -21
  167. package/dist/v3/segments.js.map +1 -1
  168. package/dist/v3/syntax.d.ts +15 -11
  169. package/dist/v3/syntax.d.ts.map +1 -1
  170. package/dist/v3/syntax.js +30 -15
  171. package/dist/v3/syntax.js.map +1 -1
  172. package/package.json +1 -1
  173. package/src/client.ts +58 -17
  174. package/src/core/account.ts +91 -35
  175. package/src/core/amount.ts +42 -9
  176. package/src/core/balance.ts +6 -0
  177. package/src/core/bank-info.ts +28 -4
  178. package/src/core/client.ts +42 -15
  179. package/src/core/config.ts +37 -18
  180. package/src/core/errors.ts +27 -7
  181. package/src/core/feedback.ts +12 -1
  182. package/src/core/transaction.ts +13 -0
  183. package/src/core/transport.ts +62 -16
  184. package/src/formats/camt.ts +62 -51
  185. package/src/formats/mt940.ts +114 -78
  186. package/src/formats/readers.ts +6 -2
  187. package/src/formats/sepa-purpose.ts +17 -9
  188. package/src/session/dialog-runner.ts +34 -7
  189. package/src/session/login-guard.ts +29 -13
  190. package/src/session/session-setup.ts +27 -9
  191. package/src/session/session-state.ts +25 -8
  192. package/src/session/signed-dialog.ts +60 -30
  193. package/src/session/user-prompts.ts +28 -3
  194. package/src/tan/challenge.ts +50 -36
  195. package/src/tan/flicker.ts +40 -29
  196. package/src/tan/tan-image.ts +9 -2
  197. package/src/tan/tan-models.ts +16 -2
  198. package/src/util/arguments.ts +40 -0
  199. package/src/util/async.ts +10 -4
  200. package/src/util/bytes.ts +3 -3
  201. package/src/util/dates.ts +52 -38
  202. package/src/util/errors.ts +9 -4
  203. package/src/util/immutable-map.ts +15 -12
  204. package/src/util/inspect.ts +14 -0
  205. package/src/util/text.ts +47 -5
  206. package/src/util/xml.ts +105 -38
  207. package/src/v3/bank-connection.ts +65 -6
  208. package/src/v3/dialog.ts +18 -8
  209. package/src/v3/message.ts +81 -72
  210. package/src/v3/parameter-store.ts +82 -16
  211. package/src/v3/parameters.ts +68 -41
  212. package/src/v3/protocol.ts +61 -28
  213. package/src/v3/queries.ts +26 -18
  214. package/src/v3/segments.ts +32 -20
  215. package/src/v3/syntax.ts +31 -14
package/dist/util/text.js CHANGED
@@ -2,6 +2,7 @@ import { base64Decode, fromCharCodes, latin1Decode, utf8Decode } from './bytes.j
2
2
  import { FormatError } from './errors.js';
3
3
  const xmlEncodingDeclaration = /encoding\s*=\s*["']([A-Za-z0-9._-]+)["']/;
4
4
  const whitespace = /\s/g;
5
+ const whiteSpaceCharacter = /\s/;
5
6
  /**
6
7
  * Decodes text from the bank, which may be UTF-8 (with or without BOM) or ISO 8859-1; ASCII reads the same in both.
7
8
  *
@@ -66,6 +67,10 @@ export function decodeWindows1252(bytes) {
66
67
  export function maskedId(id) {
67
68
  return id.length <= 4 ? '…' : `…${id.substring(id.length - 4)}`;
68
69
  }
70
+ /** `count` and `noun`, in the plural unless `count` is 1, such as `3 transactions`. */
71
+ export function counted(count, noun) {
72
+ return `${count} ${noun}${count === 1 ? '' : 's'}`;
73
+ }
69
74
  /** Whether `value` fits into ISO 8859-1, the FinTS 3.0 character set. */
70
75
  export function isLatin1(value) {
71
76
  for (let i = 0; i < value.length; i++)
@@ -73,9 +78,31 @@ export function isLatin1(value) {
73
78
  return false;
74
79
  return true;
75
80
  }
76
- /** `text` without blanks around it; `undefined` if that leaves nothing. */
81
+ /**
82
+ * Whether the UTF-16 code unit `code` is a blank: white space to `String.prototype.trim`, or U+0085 (NEL), which it
83
+ * keeps although Unicode counts it as white space. ISO 8859-1 bank data hold it as the byte 0x85.
84
+ */
85
+ function isBlank(code) {
86
+ // Below U+1680, the first white space beyond these, without a regular expression, which takes many times as long.
87
+ if (code < 0x1680)
88
+ return code === 0x20 || (code >= 0x09 && code <= 0x0d) || code === 0x85 || code === 0xa0;
89
+ return whiteSpaceCharacter.test(String.fromCharCode(code));
90
+ }
91
+ /** `text` without blanks (`isBlank`) at its `start` and its `end`. */
92
+ export function trimBlanks(text, { start = true, end = true } = {}) {
93
+ let first = 0;
94
+ let last = text.length;
95
+ if (start)
96
+ while (first < last && isBlank(text.charCodeAt(first)))
97
+ first++;
98
+ if (end)
99
+ while (last > first && isBlank(text.charCodeAt(last - 1)))
100
+ last--;
101
+ return text.substring(first, last);
102
+ }
103
+ /** `text` without blanks around it (`trimBlanks`); `undefined` if that leaves nothing. */
77
104
  export function nonBlank(text) {
78
- const trimmed = text?.trim();
105
+ const trimmed = text === undefined ? undefined : trimBlanks(text);
79
106
  return trimmed === '' ? undefined : trimmed;
80
107
  }
81
108
  /**
@@ -89,6 +116,15 @@ export function characterReference(name) {
89
116
  const code = m[1] === undefined ? parseInt(m[2], 10) : parseInt(m[1], 16);
90
117
  return code > 0 && (code < 0xd800 || code > 0xdfff) && code <= 0x10ffff ? String.fromCodePoint(code) : undefined;
91
118
  }
119
+ /**
120
+ * `text` with its full-width characters, which East Asian input methods type, as their ASCII counterparts: U+FF01 to
121
+ * U+FF5E as U+0021 to U+007E, and the ideographic space U+3000 as a blank.
122
+ */
123
+ export function withAsciiForms(text) {
124
+ return text
125
+ .replace(/[\uff01-\uff5e]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xfee0))
126
+ .replaceAll('\u3000', ' ');
127
+ }
92
128
  /** `text` without spaces and line breaks. */
93
129
  export function withoutWhitespace(text) {
94
130
  return text.replace(whitespace, '');
@@ -97,11 +133,20 @@ export function withoutWhitespace(text) {
97
133
  export function decodeBase64Lines(text) {
98
134
  return base64Decode(withoutWhitespace(text));
99
135
  }
100
- /** The integer `text` states, decimal digits with an optional sign and blanks around; `undefined` for anything else. */
136
+ /**
137
+ * The integer `text` states, decimal digits with an optional sign and blanks around, `-0` as 0; `undefined` for
138
+ * anything else, such as hex, and for a value beyond `Number.MAX_SAFE_INTEGER`, which a number holds only
139
+ * approximately.
140
+ */
101
141
  export function tryParseInt(text) {
102
142
  if (text === undefined)
103
143
  return undefined;
104
- const match = /^\s*([+-]?\d+)\s*$/.exec(text);
105
- return match ? Number(match[1]) : undefined;
144
+ const integer = trimBlanks(text);
145
+ if (!/^[+-]?\d+$/.test(integer))
146
+ return undefined;
147
+ const value = Number(integer);
148
+ if (!Number.isSafeInteger(value))
149
+ return undefined;
150
+ return value === 0 ? 0 : value;
106
151
  }
107
152
  //# sourceMappingURL=text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/util/text.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/util/text.ts"],"names":[],"mappings":"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"}
@@ -5,18 +5,19 @@
5
5
  export declare class XmlElement {
6
6
  /** The name without namespace prefix. */
7
7
  readonly localName: string;
8
- /** The attributes by name without namespace prefix; namespace declarations are left out. */
8
+ /** The attributes by name, namespace prefix and all. */
9
9
  readonly attributes: ReadonlyMap<string, string>;
10
10
  readonly children: (XmlElement | string)[];
11
11
  constructor(
12
12
  /** The name without namespace prefix. */
13
13
  localName: string,
14
- /** The attributes by name without namespace prefix; namespace declarations are left out. */
14
+ /** The attributes by name, namespace prefix and all. */
15
15
  attributes: ReadonlyMap<string, string>);
16
16
  get childElements(): XmlElement[];
17
17
  /** The text of this element and all below it. */
18
18
  get innerText(): string;
19
- getAttribute(localName: string): string | undefined;
19
+ /** The attribute called `name`: an unprefixed name finds no prefixed attribute, which is of another namespace. */
20
+ getAttribute(name: string): string | undefined;
20
21
  /** The first child element called `localName`. */
21
22
  child(localName: string): XmlElement | undefined;
22
23
  /** The element reached by following child names along `path`; this element for an empty path. */
@@ -28,7 +29,8 @@ export declare class XmlElement {
28
29
  }
29
30
  /**
30
31
  * Parses an XML document and returns its root element; throws `FormatError` if it is not well-formed, nests elements
31
- * deeper than 256 levels or holds more than a million elements and attributes.
32
+ * deeper than 100 levels, or holds more than 500,000 nodes besides text (elements, attributes, comments, processing
33
+ * instructions, the XML declaration and CDATA sections) or one per 16 characters, whichever is more.
32
34
  *
33
35
  * A document type declaration is refused: bank data have none, and its entities could expand without limit.
34
36
  */
@@ -1 +1 @@
1
- {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/util/xml.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,UAAU;IAInB,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IANlD,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAAM;;IAG9C,yCAAyC;IAChC,SAAS,EAAE,MAAM;IAC1B,4FAA4F;IACnF,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IAGlD,IAAI,aAAa,IAAI,UAAU,EAAE,CAEhC;IAED,iDAAiD;IACjD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD,kDAAkD;IAClD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIhD,iGAAiG;IACjG,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS;IAInD,2FAA2F;IAC3F,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS;IAInD,gEAAgE;IAChE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE;CAG/C;AAiDD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA8EhD"}
1
+ {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/util/xml.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,UAAU;IAInB,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IANlD,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAAM;;IAG9C,yCAAyC;IAChC,SAAS,EAAE,MAAM;IAC1B,wDAAwD;IAC/C,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IAGlD,IAAI,aAAa,IAAI,UAAU,EAAE,CAEhC;IAED,iDAAiD;IACjD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,kHAAkH;IAClH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI9C,kDAAkD;IAClD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIhD,iGAAiG;IACjG,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS;IAInD,2FAA2F;IAC3F,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS;IAInD,gEAAgE;IAChE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE;CAG/C;AAuFD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAyGhD"}
package/dist/util/xml.js CHANGED
@@ -11,7 +11,7 @@ export class XmlElement {
11
11
  constructor(
12
12
  /** The name without namespace prefix. */
13
13
  localName,
14
- /** The attributes by name without namespace prefix; namespace declarations are left out. */
14
+ /** The attributes by name, namespace prefix and all. */
15
15
  attributes) {
16
16
  this.localName = localName;
17
17
  this.attributes = attributes;
@@ -23,8 +23,9 @@ export class XmlElement {
23
23
  get innerText() {
24
24
  return this.children.map((c) => (c instanceof XmlElement ? c.innerText : c)).join('');
25
25
  }
26
- getAttribute(localName) {
27
- return this.attributes.get(localName);
26
+ /** The attribute called `name`: an unprefixed name finds no prefixed attribute, which is of another namespace. */
27
+ getAttribute(name) {
28
+ return this.attributes.get(name);
28
29
  }
29
30
  /** The first child element called `localName`. */
30
31
  child(localName) {
@@ -43,8 +44,25 @@ export class XmlElement {
43
44
  return this.children.filter((c) => c instanceof XmlElement && c.localName === localName);
44
45
  }
45
46
  }
46
- const namePattern = /[^\s<>/=!?"']+/y;
47
- const attributePattern = /\s+([^\s<>/=!?"']+)\s*=\s*(?:"([^"<]*)"|'([^'<]*)')/y;
47
+ /** The characters an XML name starts with (XML 1.0, production 4). */
48
+ const nameStartCharacters = String.raw `:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u{10000}-\u{EFFFF}`;
49
+ /**
50
+ * An XML name (XML 1.0, production 5). The combining marks lead the class of the characters after the first: after
51
+ * another one, ESLint's `no-misleading-character-class` takes them for a combined character.
52
+ */
53
+ const xmlName = String.raw `[${nameStartCharacters}][\u0300-\u036F${nameStartCharacters}\-.0-9\u00B7\u203F-\u2040]*`;
54
+ const namePattern = new RegExp(xmlName, 'uy');
55
+ /**
56
+ * White space to Unicode, U+0085 (NEL) among them, which separates the parts of a tag, and `<?xml` of the rest of the
57
+ * XML declaration, as the Dart package has it.
58
+ */
59
+ const blank = String.raw `[\s\u0085]`;
60
+ const blankPattern = new RegExp(blank);
61
+ const attributePattern = new RegExp(String.raw `${blank}+(${xmlName})${blank}*=${blank}*(?:"([^"<]*)"|'([^'<]*)')`, 'uy');
62
+ /** The start of the XML declaration, whose content is not read. */
63
+ const declarationPattern = new RegExp(String.raw `<\?xml(?:${blank}|\?>)`, 'y');
64
+ /** The text of a reference after its `&`, up to the `;` that ends it. */
65
+ const referenceNamePattern = /[^;&\s]*/y;
48
66
  /** The match of the sticky `pattern` at `position` in `text`. */
49
67
  function matchAt(pattern, text, position) {
50
68
  pattern.lastIndex = position;
@@ -58,48 +76,72 @@ const predefinedEntities = new Map([
58
76
  ['apos', "'"],
59
77
  ]);
60
78
  /** Deepest nesting of elements the parser takes: camt needs fewer than 20 levels, and `innerText` recurses. */
61
- const maxDepth = 256;
79
+ const maxDepth = 100;
62
80
  /**
63
- * Most elements and attributes one document may hold. Real camt spends about 20 bytes on each, so the largest answer a
64
- * bank can send holds fewer than 600,000, while a hostile document stays within about 150 MB of memory.
81
+ * Most nodes besides text a document may hold, unless it is long enough for one node per `charactersPerNode`
82
+ * characters: real camt spends 16 to 40 characters on each, while nodes as short as `<a/>` take a hundred times their
83
+ * length in memory.
65
84
  */
66
- const maxNodes = 1_000_000;
85
+ const maxNodes = 500_000;
86
+ const charactersPerNode = 16;
67
87
  const noAttributes = new Map();
88
+ /** The name without namespace prefix; `:a` has none, but is no unprefixed `a` either. */
68
89
  function localNameOf(qualified) {
69
90
  const colon = qualified.indexOf(':');
70
- return colon < 0 ? qualified : qualified.substring(colon + 1);
91
+ return colon > 0 ? qualified.substring(colon + 1) : qualified;
71
92
  }
72
- /** Resolves the character and predefined entity references in `text`; throws `FormatError` for any other. */
93
+ /**
94
+ * Resolves the character and predefined entity references in `text`; throws `FormatError` for any other, at the first.
95
+ * A global `replace` would find all of them before it looked at the first: a gigabyte for megabytes of `&`.
96
+ */
73
97
  function decodeEntities(text) {
74
- return text.replace(/&([^;&\s]*);?/g, (match, name) => {
75
- if (!match.endsWith(';'))
98
+ let decoded = '';
99
+ let position = 0;
100
+ for (let ampersand = text.indexOf('&'); ampersand >= 0; ampersand = text.indexOf('&', position)) {
101
+ const name = matchAt(referenceNamePattern, text, ampersand + 1)[0];
102
+ const end = ampersand + 1 + name.length;
103
+ if (text.charAt(end) !== ';')
76
104
  throw new FormatError('Invalid XML: unterminated entity reference');
77
- if (name.startsWith('#')) {
78
- const character = characterReference(name);
79
- if (character === undefined)
80
- throw new FormatError('Invalid XML character reference', match);
81
- return character;
82
- }
83
- const value = predefinedEntities.get(name);
84
- if (value === undefined)
85
- throw new FormatError('Invalid XML: unknown entity', match);
86
- return value;
87
- });
105
+ decoded += text.substring(position, ampersand) + resolved(name, text.substring(ampersand, end + 1));
106
+ position = end + 1;
107
+ }
108
+ return position === 0 ? text : decoded + text.substring(position);
109
+ }
110
+ /** The text the `reference` called `name` stands for. */
111
+ function resolved(name, reference) {
112
+ if (name.startsWith('#')) {
113
+ const character = characterReference(name);
114
+ if (character === undefined)
115
+ throw new FormatError('Invalid XML character reference', reference);
116
+ return character;
117
+ }
118
+ const value = predefinedEntities.get(name);
119
+ if (value === undefined)
120
+ throw new FormatError('Invalid XML: unknown entity', reference);
121
+ return value;
88
122
  }
89
123
  /**
90
124
  * Parses an XML document and returns its root element; throws `FormatError` if it is not well-formed, nests elements
91
- * deeper than 256 levels or holds more than a million elements and attributes.
125
+ * deeper than 100 levels, or holds more than 500,000 nodes besides text (elements, attributes, comments, processing
126
+ * instructions, the XML declaration and CDATA sections) or one per 16 characters, whichever is more.
92
127
  *
93
128
  * A document type declaration is refused: bank data have none, and its entities could expand without limit.
94
129
  */
95
130
  export function parseXml(xml) {
96
131
  let position = 0;
97
132
  const stack = [];
133
+ const openNames = [];
98
134
  let root;
135
+ let declared = false;
99
136
  let nodes = 0;
137
+ const nodeLimit = Math.max(maxNodes, Math.floor(xml.length / charactersPerNode));
100
138
  const fail = (reason) => {
101
139
  throw new FormatError(`Invalid XML: ${reason} at position ${position}`);
102
140
  };
141
+ const countNode = () => {
142
+ if (++nodes > nodeLimit)
143
+ fail(`more than ${nodeLimit} nodes`);
144
+ };
103
145
  const skipPast = (terminator, what) => {
104
146
  const end = xml.indexOf(terminator, position);
105
147
  if (end < 0)
@@ -111,22 +153,42 @@ export function parseXml(xml) {
111
153
  const textEnd = lt < 0 ? xml.length : lt;
112
154
  if (textEnd > position) {
113
155
  const text = xml.substring(position, textEnd);
114
- const parent = stack.at(-1);
115
- if (parent)
116
- parent.children.push(decodeEntities(text));
117
- else if (text.trim() !== '')
118
- fail('text outside the root element');
156
+ // Blanks are dropped only where they follow no text, as between elements: kept, they would double the nodes of a
157
+ // document with line breaks. Between two texts they are content, and a counted node separates the two.
158
+ if (nonBlank(text) !== undefined || typeof stack.at(-1)?.children.at(-1) === 'string') {
159
+ (stack.at(-1) ?? fail('text outside the root element')).children.push(decodeEntities(text));
160
+ }
119
161
  position = textEnd;
120
162
  continue;
121
163
  }
122
164
  if (xml.startsWith('<?', position)) {
165
+ countNode();
166
+ if (matchAt(declarationPattern, xml, position)) {
167
+ if (root)
168
+ fail('XML declaration inside or after the root element');
169
+ if (declared)
170
+ fail('a second XML declaration');
171
+ declared = true;
172
+ }
173
+ else {
174
+ position += 2;
175
+ const target = matchAt(namePattern, xml, position)?.[0] ?? fail('missing processing instruction target');
176
+ position += target.length;
177
+ if (!xml.startsWith('?>', position) && !blankPattern.test(xml.charAt(position))) {
178
+ fail('malformed processing instruction');
179
+ }
180
+ }
123
181
  skipPast('?>', 'processing instruction');
124
182
  }
125
183
  else if (xml.startsWith('<!--', position)) {
184
+ countNode();
185
+ // Past the `<!--`, whose dashes end no comment: `<!-->` starts one.
186
+ position += 4;
126
187
  skipPast('-->', 'comment');
127
188
  }
128
189
  else if (xml.startsWith('<![CDATA[', position)) {
129
190
  const parent = stack.at(-1) ?? fail('CDATA outside the root element');
191
+ countNode();
130
192
  const start = position + 9;
131
193
  skipPast(']]>', 'CDATA section');
132
194
  parent.children.push(xml.substring(start, position - 3));
@@ -138,20 +200,19 @@ export function parseXml(xml) {
138
200
  position += 2;
139
201
  const name = matchAt(namePattern, xml, position)?.[0] ?? fail('missing end tag name');
140
202
  position += name.length;
141
- while (/\s/.test(xml.charAt(position)))
203
+ while (blankPattern.test(xml.charAt(position)))
142
204
  position++;
143
205
  if (xml.charAt(position) !== '>')
144
206
  fail('malformed end tag');
145
207
  position++;
146
- const open = stack.pop();
147
- if (open === undefined || open.localName !== localNameOf(name))
208
+ stack.pop();
209
+ if (openNames.pop() !== name)
148
210
  fail(`unexpected end tag ${name}`);
149
211
  }
150
212
  else {
151
213
  if (stack.length >= maxDepth)
152
214
  fail(`elements nested deeper than ${maxDepth} levels`);
153
- if (++nodes > maxNodes)
154
- fail(`more than ${maxNodes} elements and attributes`);
215
+ countNode();
155
216
  position++;
156
217
  const name = matchAt(namePattern, xml, position)?.[0] ?? fail('missing element name');
157
218
  position += name.length;
@@ -161,15 +222,14 @@ export function parseXml(xml) {
161
222
  if (!attribute)
162
223
  break;
163
224
  position += attribute[0].length;
164
- if (++nodes > maxNodes)
165
- fail(`more than ${maxNodes} elements and attributes`);
225
+ countNode();
166
226
  const attributeName = attribute[1];
167
- if (attributeName !== 'xmlns' && !attributeName.startsWith('xmlns:')) {
168
- attributes ??= new Map();
169
- attributes.set(localNameOf(attributeName), decodeEntities(attribute[2] ?? attribute[3] ?? ''));
170
- }
227
+ attributes ??= new Map();
228
+ if (attributes.has(attributeName))
229
+ fail(`duplicate attribute ${attributeName}`);
230
+ attributes.set(attributeName, decodeEntities(attribute[2] ?? attribute[3] ?? ''));
171
231
  }
172
- while (/\s/.test(xml.charAt(position)))
232
+ while (blankPattern.test(xml.charAt(position)))
173
233
  position++;
174
234
  const selfClosing = xml.startsWith('/>', position);
175
235
  if (!selfClosing && xml.charAt(position) !== '>')
@@ -183,12 +243,14 @@ export function parseXml(xml) {
183
243
  fail('a second root element');
184
244
  else
185
245
  root = element;
186
- if (!selfClosing)
246
+ if (!selfClosing) {
187
247
  stack.push(element);
248
+ openNames.push(name);
249
+ }
188
250
  }
189
251
  }
190
252
  if (stack.length > 0)
191
- fail(`unclosed element ${stack.at(-1).localName}`);
253
+ fail(`unclosed element ${openNames.at(-1)}`);
192
254
  return root ?? fail('no root element');
193
255
  }
194
256
  //# sourceMappingURL=xml.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"xml.js","sourceRoot":"","sources":["../../src/util/xml.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xml.js","sourceRoot":"","sources":["../../src/util/xml.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,14 @@ export declare class BankConnection {
11
11
  private readonly transport;
12
12
  /** Where the messages go, as `FinTsConfig` checked it. */
13
13
  private readonly href;
14
- /** Aborts the requests on their way (`abortRequests`). */
14
+ /** Aborts the requests posted since the last `abortRequestsAfter`. */
15
15
  private requests;
16
+ /** How many requests are on their way. */
17
+ private onTheirWay;
18
+ /** Starts the time of the requests posted after `abortRequestsAfter`, once none posted before is on its way. */
19
+ private startLaterRequests;
20
+ /** The timers of `abortRequestsAfter`, which `close` clears. */
21
+ private readonly deadlines;
16
22
  /** A connection to `url` through `transport`, an `HttpTransport` by default. */
17
23
  constructor(url: URL, transport: FinTsTransport | undefined, logger: MessageLogger | undefined);
18
24
  /**
@@ -23,12 +29,26 @@ export declare class BankConnection {
23
29
  * `TypeError` where the network does, and one that throws another `FinTsError`, such as `FinTsPinError`, would pass
24
30
  * for an answer of the bank. Of such an error only the message is kept (`failureMessage`), since it may hold `body`,
25
31
  * as the errors of HTTP clients such as axios do.
32
+ *
33
+ * Once the time `abortRequestsAfter` gives is up, it fails at once, before anything reaches the transport
34
+ * (`checkSendable`), and a request on its way fails then without waiting for the transport, which may ignore the
35
+ * abort.
26
36
  */
27
37
  post(body: Uint8Array, contentType: string): Promise<Uint8Array>;
38
+ /**
39
+ * Throws the `FinTsTransportError` that `post` fails with once the time `abortRequestsAfter` gives is up; a caller
40
+ * checks it before it reports a message as outgoing, since such a message never goes out.
41
+ */
42
+ checkSendable(): void;
28
43
  /** Reports a message to the logger; `message` is only built when a logger is set. */
29
44
  log(direction: MessageDirection, message: () => string): void;
30
- /** Aborts the requests on their way; those posted afterwards, such as the dialog ends of a closing client, go out. */
31
- abortRequests(): void;
45
+ /**
46
+ * Gives the requests on their way `graceMs` to finish, and aborts them then. Those posted later, such as the dialog
47
+ * ends of a closing client, have as long again from the moment the earlier ones are over or aborted, and are aborted
48
+ * in turn once that time is up, as is any posted after it: a bank that has stopped answering would hold them up to
49
+ * the transport's timeout.
50
+ */
51
+ abortRequestsAfter(graceMs: number): void;
32
52
  close(): void;
33
53
  }
34
54
  //# sourceMappingURL=bank-connection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bank-connection.d.ts","sourceRoot":"","sources":["../../src/v3/bank-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAI9E;AAED,sFAAsF;AACtF,qBAAa,cAAc;IAavB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAE3C,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAyB;IAEzC,gFAAgF;gBAE9E,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,cAAc,GAAG,SAAS,EACpB,MAAM,EAAE,aAAa,GAAG,SAAS;IAMpD;;;;;;;;OAQG;IACG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAStE,qFAAqF;IACrF,GAAG,CAAC,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,MAAM,GAAG,IAAI;IAI7D,sHAAsH;IACtH,aAAa,IAAI,IAAI;IAKrB,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"bank-connection.d.ts","sourceRoot":"","sources":["../../src/v3/bank-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAI9E;AAED,sFAAsF;AACtF,qBAAa,cAAc;IAsBvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IArBzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAE3C,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAyB;IAEzC,0CAA0C;IAC1C,OAAO,CAAC,UAAU,CAAK;IAEvB,gHAAgH;IAChH,OAAO,CAAC,kBAAkB,CAA2B;IAErD,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IAEjE,gFAAgF;gBAE9E,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,cAAc,GAAG,SAAS,EACpB,MAAM,EAAE,aAAa,GAAG,SAAS;IAMpD;;;;;;;;;;;;OAYG;IACG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuBtE;;;OAGG;IACH,aAAa,IAAI,IAAI;IAIrB,qFAAqF;IACrF,GAAG,CAAC,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,MAAM,GAAG,IAAI;IAI7D;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAuBzC,KAAK,IAAI,IAAI;CAId"}
@@ -15,8 +15,14 @@ export class BankConnection {
15
15
  transport;
16
16
  /** Where the messages go, as `FinTsConfig` checked it. */
17
17
  href;
18
- /** Aborts the requests on their way (`abortRequests`). */
18
+ /** Aborts the requests posted since the last `abortRequestsAfter`. */
19
19
  requests = new AbortController();
20
+ /** How many requests are on their way. */
21
+ onTheirWay = 0;
22
+ /** Starts the time of the requests posted after `abortRequestsAfter`, once none posted before is on its way. */
23
+ startLaterRequests;
24
+ /** The timers of `abortRequestsAfter`, which `close` clears. */
25
+ deadlines = [];
20
26
  /** A connection to `url` through `transport`, an `HttpTransport` by default. */
21
27
  constructor(url, transport, logger) {
22
28
  this.logger = logger;
@@ -31,27 +37,81 @@ export class BankConnection {
31
37
  * `TypeError` where the network does, and one that throws another `FinTsError`, such as `FinTsPinError`, would pass
32
38
  * for an answer of the bank. Of such an error only the message is kept (`failureMessage`), since it may hold `body`,
33
39
  * as the errors of HTTP clients such as axios do.
40
+ *
41
+ * Once the time `abortRequestsAfter` gives is up, it fails at once, before anything reaches the transport
42
+ * (`checkSendable`), and a request on its way fails then without waiting for the transport, which may ignore the
43
+ * abort.
34
44
  */
35
45
  async post(body, contentType) {
46
+ this.checkSendable();
47
+ const signal = this.requests.signal;
48
+ let stopWaiting;
49
+ const aborted = new Promise((_, reject) => {
50
+ stopWaiting = () => {
51
+ reject(new FinTsTransportError('Request aborted'));
52
+ };
53
+ });
54
+ signal.addEventListener('abort', stopWaiting);
55
+ this.onTheirWay++;
36
56
  try {
37
- return await this.transport.post(new URL(this.href), body, contentType, this.requests.signal);
57
+ return await Promise.race([this.transport.post(new URL(this.href), body, contentType, signal), aborted]);
38
58
  }
39
59
  catch (error) {
40
60
  if (error instanceof FinTsTransportError)
41
61
  throw error;
42
62
  throw new FinTsTransportError(failureMessage(error));
43
63
  }
64
+ finally {
65
+ signal.removeEventListener('abort', stopWaiting);
66
+ this.onTheirWay--;
67
+ if (this.onTheirWay === 0)
68
+ this.startLaterRequests?.();
69
+ }
70
+ }
71
+ /**
72
+ * Throws the `FinTsTransportError` that `post` fails with once the time `abortRequestsAfter` gives is up; a caller
73
+ * checks it before it reports a message as outgoing, since such a message never goes out.
74
+ */
75
+ checkSendable() {
76
+ if (this.requests.signal.aborted)
77
+ throw new FinTsTransportError('Request aborted');
44
78
  }
45
79
  /** Reports a message to the logger; `message` is only built when a logger is set. */
46
80
  log(direction, message) {
47
81
  this.logger?.(direction, message());
48
82
  }
49
- /** Aborts the requests on their way; those posted afterwards, such as the dialog ends of a closing client, go out. */
50
- abortRequests() {
51
- this.requests.abort();
52
- this.requests = new AbortController();
83
+ /**
84
+ * Gives the requests on their way `graceMs` to finish, and aborts them then. Those posted later, such as the dialog
85
+ * ends of a closing client, have as long again from the moment the earlier ones are over or aborted, and are aborted
86
+ * in turn once that time is up, as is any posted after it: a bank that has stopped answering would hold them up to
87
+ * the transport's timeout.
88
+ */
89
+ abortRequestsAfter(graceMs) {
90
+ const earlier = this.requests;
91
+ const later = new AbortController();
92
+ this.requests = later;
93
+ const afterGrace = (action) => {
94
+ this.deadlines.push(setTimeout(action, graceMs));
95
+ };
96
+ this.startLaterRequests = () => {
97
+ this.startLaterRequests = undefined;
98
+ afterGrace(() => {
99
+ later.abort();
100
+ });
101
+ };
102
+ if (this.onTheirWay === 0) {
103
+ this.startLaterRequests();
104
+ }
105
+ else {
106
+ afterGrace(() => {
107
+ earlier.abort();
108
+ this.startLaterRequests?.();
109
+ });
110
+ }
53
111
  }
54
112
  close() {
113
+ for (const deadline of this.deadlines)
114
+ clearTimeout(deadline);
55
115
  this.transport.close();
56
116
  }
57
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bank-connection.js","sourceRoot":"","sources":["../../src/v3/bank-connection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAuB,MAAM,sBAAsB,CAAC;AAE1F;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,KAAyB;IACtE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC;QAC5D,MAAM,IAAI,kBAAkB,CAAC,gBAAgB,IAAI,qDAAqD,KAAK,KAAK,CAAC,CAAC;IACpH,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,OAAO,cAAc;IAaN;IAZF,SAAS,CAAiB;IAE3C,0DAA0D;IACzC,IAAI,CAAS;IAE9B,0DAA0D;IAClD,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IAEzC,gFAAgF;IAChF,YACE,GAAQ,EACR,SAAqC,EACpB,MAAiC;QAAjC,WAAM,GAAN,MAAM,CAA2B;QAElD,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,IAAI,aAAa,EAAE,CAAC;IACpD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CAAC,IAAgB,EAAE,WAAmB;QAC9C,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,mBAAmB;gBAAE,MAAM,KAAK,CAAC;YACtD,MAAM,IAAI,mBAAmB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,qFAAqF;IACrF,GAAG,CAAC,SAA2B,EAAE,OAAqB;QACpD,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,sHAAsH;IACtH,aAAa;QACX,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;IACxC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"bank-connection.js","sourceRoot":"","sources":["../../src/v3/bank-connection.ts"],"names":[],"mappings":"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"}