@coderoftime/fints 0.0.0-stage → 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 (249) hide show
  1. package/CHANGELOG.md +152 -0
  2. package/LICENSE +28 -0
  3. package/README.md +246 -2
  4. package/dist/client.d.ts +48 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +199 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/core/account.d.ts +168 -0
  9. package/dist/core/account.d.ts.map +1 -0
  10. package/dist/core/account.js +245 -0
  11. package/dist/core/account.js.map +1 -0
  12. package/dist/core/amount.d.ts +63 -0
  13. package/dist/core/amount.d.ts.map +1 -0
  14. package/dist/core/amount.js +192 -0
  15. package/dist/core/amount.js.map +1 -0
  16. package/dist/core/balance.d.ts +55 -0
  17. package/dist/core/balance.d.ts.map +1 -0
  18. package/dist/core/balance.js +54 -0
  19. package/dist/core/balance.js.map +1 -0
  20. package/dist/core/bank-info.d.ts +49 -0
  21. package/dist/core/bank-info.d.ts.map +1 -0
  22. package/dist/core/bank-info.js +52 -0
  23. package/dist/core/bank-info.js.map +1 -0
  24. package/dist/core/client.d.ts +161 -0
  25. package/dist/core/client.d.ts.map +1 -0
  26. package/dist/core/client.js +2 -0
  27. package/dist/core/client.js.map +1 -0
  28. package/dist/core/config.d.ts +80 -0
  29. package/dist/core/config.d.ts.map +1 -0
  30. package/dist/core/config.js +153 -0
  31. package/dist/core/config.js.map +1 -0
  32. package/dist/core/errors.d.ts +153 -0
  33. package/dist/core/errors.d.ts.map +1 -0
  34. package/dist/core/errors.js +247 -0
  35. package/dist/core/errors.js.map +1 -0
  36. package/dist/core/feedback.d.ts +72 -0
  37. package/dist/core/feedback.d.ts.map +1 -0
  38. package/dist/core/feedback.js +127 -0
  39. package/dist/core/feedback.js.map +1 -0
  40. package/dist/core/transaction.d.ts +103 -0
  41. package/dist/core/transaction.d.ts.map +1 -0
  42. package/dist/core/transaction.js +96 -0
  43. package/dist/core/transaction.js.map +1 -0
  44. package/dist/core/transport.d.ts +64 -0
  45. package/dist/core/transport.d.ts.map +1 -0
  46. package/dist/core/transport.js +149 -0
  47. package/dist/core/transport.js.map +1 -0
  48. package/dist/formats/camt.d.ts +32 -0
  49. package/dist/formats/camt.d.ts.map +1 -0
  50. package/dist/formats/camt.js +242 -0
  51. package/dist/formats/camt.js.map +1 -0
  52. package/dist/formats/mt940.d.ts +54 -0
  53. package/dist/formats/mt940.d.ts.map +1 -0
  54. package/dist/formats/mt940.js +376 -0
  55. package/dist/formats/mt940.js.map +1 -0
  56. package/dist/formats/readers.d.ts +15 -0
  57. package/dist/formats/readers.d.ts.map +1 -0
  58. package/dist/formats/readers.js +42 -0
  59. package/dist/formats/readers.js.map +1 -0
  60. package/dist/formats/record-budget.d.ts +7 -0
  61. package/dist/formats/record-budget.d.ts.map +1 -0
  62. package/dist/formats/record-budget.js +17 -0
  63. package/dist/formats/record-budget.js.map +1 -0
  64. package/dist/formats/sepa-purpose.d.ts +28 -0
  65. package/dist/formats/sepa-purpose.d.ts.map +1 -0
  66. package/dist/formats/sepa-purpose.js +89 -0
  67. package/dist/formats/sepa-purpose.js.map +1 -0
  68. package/dist/index.d.ts +28 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +27 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/session/app-approval.d.ts +66 -0
  73. package/dist/session/app-approval.d.ts.map +1 -0
  74. package/dist/session/app-approval.js +226 -0
  75. package/dist/session/app-approval.js.map +1 -0
  76. package/dist/session/dialog-runner.d.ts +31 -0
  77. package/dist/session/dialog-runner.d.ts.map +1 -0
  78. package/dist/session/dialog-runner.js +111 -0
  79. package/dist/session/dialog-runner.js.map +1 -0
  80. package/dist/session/login-guard.d.ts +78 -0
  81. package/dist/session/login-guard.d.ts.map +1 -0
  82. package/dist/session/login-guard.js +181 -0
  83. package/dist/session/login-guard.js.map +1 -0
  84. package/dist/session/sepa-accounts.d.ts +40 -0
  85. package/dist/session/sepa-accounts.d.ts.map +1 -0
  86. package/dist/session/sepa-accounts.js +112 -0
  87. package/dist/session/sepa-accounts.js.map +1 -0
  88. package/dist/session/session-setup.d.ts +80 -0
  89. package/dist/session/session-setup.d.ts.map +1 -0
  90. package/dist/session/session-setup.js +182 -0
  91. package/dist/session/session-setup.js.map +1 -0
  92. package/dist/session/session-state.d.ts +50 -0
  93. package/dist/session/session-state.d.ts.map +1 -0
  94. package/dist/session/session-state.js +182 -0
  95. package/dist/session/session-state.js.map +1 -0
  96. package/dist/session/signed-dialog.d.ts +77 -0
  97. package/dist/session/signed-dialog.d.ts.map +1 -0
  98. package/dist/session/signed-dialog.js +170 -0
  99. package/dist/session/signed-dialog.js.map +1 -0
  100. package/dist/session/tan-selection.d.ts +96 -0
  101. package/dist/session/tan-selection.d.ts.map +1 -0
  102. package/dist/session/tan-selection.js +189 -0
  103. package/dist/session/tan-selection.js.map +1 -0
  104. package/dist/session/user-prompts.d.ts +65 -0
  105. package/dist/session/user-prompts.d.ts.map +1 -0
  106. package/dist/session/user-prompts.js +184 -0
  107. package/dist/session/user-prompts.js.map +1 -0
  108. package/dist/tan/challenge.d.ts +135 -0
  109. package/dist/tan/challenge.d.ts.map +1 -0
  110. package/dist/tan/challenge.js +184 -0
  111. package/dist/tan/challenge.js.map +1 -0
  112. package/dist/tan/flicker.d.ts +42 -0
  113. package/dist/tan/flicker.d.ts.map +1 -0
  114. package/dist/tan/flicker.js +296 -0
  115. package/dist/tan/flicker.js.map +1 -0
  116. package/dist/tan/tan-image.d.ts +22 -0
  117. package/dist/tan/tan-image.d.ts.map +1 -0
  118. package/dist/tan/tan-image.js +43 -0
  119. package/dist/tan/tan-image.js.map +1 -0
  120. package/dist/tan/tan-models.d.ts +149 -0
  121. package/dist/tan/tan-models.d.ts.map +1 -0
  122. package/dist/tan/tan-models.js +153 -0
  123. package/dist/tan/tan-models.js.map +1 -0
  124. package/dist/util/async.d.ts +22 -0
  125. package/dist/util/async.d.ts.map +1 -0
  126. package/dist/util/async.js +45 -0
  127. package/dist/util/async.js.map +1 -0
  128. package/dist/util/bytes.d.ts +22 -0
  129. package/dist/util/bytes.d.ts.map +1 -0
  130. package/dist/util/bytes.js +128 -0
  131. package/dist/util/bytes.js.map +1 -0
  132. package/dist/util/call-context.d.ts +12 -0
  133. package/dist/util/call-context.d.ts.map +1 -0
  134. package/dist/util/call-context.js +30 -0
  135. package/dist/util/call-context.js.map +1 -0
  136. package/dist/util/dates.d.ts +55 -0
  137. package/dist/util/dates.d.ts.map +1 -0
  138. package/dist/util/dates.js +189 -0
  139. package/dist/util/dates.js.map +1 -0
  140. package/dist/util/errors.d.ts +17 -0
  141. package/dist/util/errors.d.ts.map +1 -0
  142. package/dist/util/errors.js +24 -0
  143. package/dist/util/errors.js.map +1 -0
  144. package/dist/util/immutable-map.d.ts +16 -0
  145. package/dist/util/immutable-map.d.ts.map +1 -0
  146. package/dist/util/immutable-map.js +38 -0
  147. package/dist/util/immutable-map.js.map +1 -0
  148. package/dist/util/json.d.ts +17 -0
  149. package/dist/util/json.d.ts.map +1 -0
  150. package/dist/util/json.js +62 -0
  151. package/dist/util/json.js.map +1 -0
  152. package/dist/util/text.d.ts +37 -0
  153. package/dist/util/text.d.ts.map +1 -0
  154. package/dist/util/text.js +107 -0
  155. package/dist/util/text.js.map +1 -0
  156. package/dist/util/xml.d.ts +36 -0
  157. package/dist/util/xml.d.ts.map +1 -0
  158. package/dist/util/xml.js +194 -0
  159. package/dist/util/xml.js.map +1 -0
  160. package/dist/v3/account-extension.d.ts +25 -0
  161. package/dist/v3/account-extension.d.ts.map +1 -0
  162. package/dist/v3/account-extension.js +173 -0
  163. package/dist/v3/account-extension.js.map +1 -0
  164. package/dist/v3/bank-connection.d.ts +34 -0
  165. package/dist/v3/bank-connection.d.ts.map +1 -0
  166. package/dist/v3/bank-connection.js +58 -0
  167. package/dist/v3/bank-connection.js.map +1 -0
  168. package/dist/v3/dialog.d.ts +112 -0
  169. package/dist/v3/dialog.d.ts.map +1 -0
  170. package/dist/v3/dialog.js +241 -0
  171. package/dist/v3/dialog.js.map +1 -0
  172. package/dist/v3/message.d.ts +85 -0
  173. package/dist/v3/message.d.ts.map +1 -0
  174. package/dist/v3/message.js +303 -0
  175. package/dist/v3/message.js.map +1 -0
  176. package/dist/v3/parameter-store.d.ts +75 -0
  177. package/dist/v3/parameter-store.d.ts.map +1 -0
  178. package/dist/v3/parameter-store.js +143 -0
  179. package/dist/v3/parameter-store.js.map +1 -0
  180. package/dist/v3/parameters.d.ts +105 -0
  181. package/dist/v3/parameters.d.ts.map +1 -0
  182. package/dist/v3/parameters.js +450 -0
  183. package/dist/v3/parameters.js.map +1 -0
  184. package/dist/v3/protocol.d.ts +61 -0
  185. package/dist/v3/protocol.d.ts.map +1 -0
  186. package/dist/v3/protocol.js +113 -0
  187. package/dist/v3/protocol.js.map +1 -0
  188. package/dist/v3/queries.d.ts +51 -0
  189. package/dist/v3/queries.d.ts.map +1 -0
  190. package/dist/v3/queries.js +120 -0
  191. package/dist/v3/queries.js.map +1 -0
  192. package/dist/v3/segments.d.ts +106 -0
  193. package/dist/v3/segments.d.ts.map +1 -0
  194. package/dist/v3/segments.js +325 -0
  195. package/dist/v3/segments.js.map +1 -0
  196. package/dist/v3/syntax.d.ts +127 -0
  197. package/dist/v3/syntax.d.ts.map +1 -0
  198. package/dist/v3/syntax.js +367 -0
  199. package/dist/v3/syntax.js.map +1 -0
  200. package/package.json +67 -4
  201. package/src/client.ts +252 -0
  202. package/src/core/account.ts +323 -0
  203. package/src/core/amount.ts +211 -0
  204. package/src/core/balance.ts +85 -0
  205. package/src/core/bank-info.ts +66 -0
  206. package/src/core/client.ts +186 -0
  207. package/src/core/config.ts +182 -0
  208. package/src/core/errors.ts +277 -0
  209. package/src/core/feedback.ts +140 -0
  210. package/src/core/transaction.ts +161 -0
  211. package/src/core/transport.ts +189 -0
  212. package/src/formats/camt.ts +266 -0
  213. package/src/formats/mt940.ts +419 -0
  214. package/src/formats/readers.ts +49 -0
  215. package/src/formats/record-budget.ts +18 -0
  216. package/src/formats/sepa-purpose.ts +94 -0
  217. package/src/index.ts +70 -0
  218. package/src/session/app-approval.ts +278 -0
  219. package/src/session/dialog-runner.ts +122 -0
  220. package/src/session/login-guard.ts +221 -0
  221. package/src/session/sepa-accounts.ts +115 -0
  222. package/src/session/session-setup.ts +184 -0
  223. package/src/session/session-state.ts +204 -0
  224. package/src/session/signed-dialog.ts +192 -0
  225. package/src/session/tan-selection.ts +203 -0
  226. package/src/session/user-prompts.ts +193 -0
  227. package/src/tan/challenge.ts +261 -0
  228. package/src/tan/flicker.ts +308 -0
  229. package/src/tan/tan-image.ts +38 -0
  230. package/src/tan/tan-models.ts +252 -0
  231. package/src/util/async.ts +48 -0
  232. package/src/util/bytes.ts +129 -0
  233. package/src/util/call-context.ts +41 -0
  234. package/src/util/dates.ts +210 -0
  235. package/src/util/errors.ts +27 -0
  236. package/src/util/immutable-map.ts +47 -0
  237. package/src/util/json.ts +67 -0
  238. package/src/util/text.ts +112 -0
  239. package/src/util/xml.ts +183 -0
  240. package/src/v3/account-extension.ts +185 -0
  241. package/src/v3/bank-connection.ts +67 -0
  242. package/src/v3/dialog.ts +283 -0
  243. package/src/v3/message.ts +373 -0
  244. package/src/v3/parameter-store.ts +160 -0
  245. package/src/v3/parameters.ts +524 -0
  246. package/src/v3/protocol.ts +148 -0
  247. package/src/v3/queries.ts +190 -0
  248. package/src/v3/segments.ts +374 -0
  249. package/src/v3/syntax.ts +369 -0
@@ -0,0 +1,194 @@
1
+ import { FormatError } from './errors.js';
2
+ import { characterReference, nonBlank } from './text.js';
3
+ /**
4
+ * An element of a parsed XML document, looked up by local name: camt documents come with and without namespace
5
+ * prefixes.
6
+ */
7
+ export class XmlElement {
8
+ localName;
9
+ attributes;
10
+ children = [];
11
+ constructor(
12
+ /** The name without namespace prefix. */
13
+ localName,
14
+ /** The attributes by name without namespace prefix; namespace declarations are left out. */
15
+ attributes) {
16
+ this.localName = localName;
17
+ this.attributes = attributes;
18
+ }
19
+ get childElements() {
20
+ return this.children.filter((c) => c instanceof XmlElement);
21
+ }
22
+ /** The text of this element and all below it. */
23
+ get innerText() {
24
+ return this.children.map((c) => (c instanceof XmlElement ? c.innerText : c)).join('');
25
+ }
26
+ getAttribute(localName) {
27
+ return this.attributes.get(localName);
28
+ }
29
+ /** The first child element called `localName`. */
30
+ child(localName) {
31
+ return this.children.find((c) => c instanceof XmlElement && c.localName === localName);
32
+ }
33
+ /** The element reached by following child names along `path`; this element for an empty path. */
34
+ at(path) {
35
+ return path.reduce((element, name) => element?.child(name), this);
36
+ }
37
+ /** The trimmed text of the element at `path`, or `undefined` if it is missing or empty. */
38
+ textAt(path) {
39
+ return nonBlank(this.at(path)?.innerText);
40
+ }
41
+ /** The child elements called `localName`, in document order. */
42
+ childrenNamed(localName) {
43
+ return this.children.filter((c) => c instanceof XmlElement && c.localName === localName);
44
+ }
45
+ }
46
+ const namePattern = /[^\s<>/=!?"']+/y;
47
+ const attributePattern = /\s+([^\s<>/=!?"']+)\s*=\s*(?:"([^"<]*)"|'([^'<]*)')/y;
48
+ /** The match of the sticky `pattern` at `position` in `text`. */
49
+ function matchAt(pattern, text, position) {
50
+ pattern.lastIndex = position;
51
+ return pattern.exec(text);
52
+ }
53
+ const predefinedEntities = new Map([
54
+ ['amp', '&'],
55
+ ['lt', '<'],
56
+ ['gt', '>'],
57
+ ['quot', '"'],
58
+ ['apos', "'"],
59
+ ]);
60
+ /** Deepest nesting of elements the parser takes: camt needs fewer than 20 levels, and `innerText` recurses. */
61
+ const maxDepth = 256;
62
+ /**
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.
65
+ */
66
+ const maxNodes = 1_000_000;
67
+ const noAttributes = new Map();
68
+ function localNameOf(qualified) {
69
+ const colon = qualified.indexOf(':');
70
+ return colon < 0 ? qualified : qualified.substring(colon + 1);
71
+ }
72
+ /** Resolves the character and predefined entity references in `text`; throws `FormatError` for any other. */
73
+ function decodeEntities(text) {
74
+ return text.replace(/&([^;&\s]*);?/g, (match, name) => {
75
+ if (!match.endsWith(';'))
76
+ 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
+ });
88
+ }
89
+ /**
90
+ * 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.
92
+ *
93
+ * A document type declaration is refused: bank data have none, and its entities could expand without limit.
94
+ */
95
+ export function parseXml(xml) {
96
+ let position = 0;
97
+ const stack = [];
98
+ let root;
99
+ let nodes = 0;
100
+ const fail = (reason) => {
101
+ throw new FormatError(`Invalid XML: ${reason} at position ${position}`);
102
+ };
103
+ const skipPast = (terminator, what) => {
104
+ const end = xml.indexOf(terminator, position);
105
+ if (end < 0)
106
+ fail(`unterminated ${what}`);
107
+ position = end + terminator.length;
108
+ };
109
+ while (position < xml.length) {
110
+ const lt = xml.indexOf('<', position);
111
+ const textEnd = lt < 0 ? xml.length : lt;
112
+ if (textEnd > position) {
113
+ 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');
119
+ position = textEnd;
120
+ continue;
121
+ }
122
+ if (xml.startsWith('<?', position)) {
123
+ skipPast('?>', 'processing instruction');
124
+ }
125
+ else if (xml.startsWith('<!--', position)) {
126
+ skipPast('-->', 'comment');
127
+ }
128
+ else if (xml.startsWith('<![CDATA[', position)) {
129
+ const parent = stack.at(-1) ?? fail('CDATA outside the root element');
130
+ const start = position + 9;
131
+ skipPast(']]>', 'CDATA section');
132
+ parent.children.push(xml.substring(start, position - 3));
133
+ }
134
+ else if (xml.startsWith('<!', position)) {
135
+ fail('document type declarations are not supported');
136
+ }
137
+ else if (xml.startsWith('</', position)) {
138
+ position += 2;
139
+ const name = matchAt(namePattern, xml, position)?.[0] ?? fail('missing end tag name');
140
+ position += name.length;
141
+ while (/\s/.test(xml.charAt(position)))
142
+ position++;
143
+ if (xml.charAt(position) !== '>')
144
+ fail('malformed end tag');
145
+ position++;
146
+ const open = stack.pop();
147
+ if (open === undefined || open.localName !== localNameOf(name))
148
+ fail(`unexpected end tag ${name}`);
149
+ }
150
+ else {
151
+ if (stack.length >= maxDepth)
152
+ fail(`elements nested deeper than ${maxDepth} levels`);
153
+ if (++nodes > maxNodes)
154
+ fail(`more than ${maxNodes} elements and attributes`);
155
+ position++;
156
+ const name = matchAt(namePattern, xml, position)?.[0] ?? fail('missing element name');
157
+ position += name.length;
158
+ let attributes;
159
+ for (;;) {
160
+ const attribute = matchAt(attributePattern, xml, position);
161
+ if (!attribute)
162
+ break;
163
+ position += attribute[0].length;
164
+ if (++nodes > maxNodes)
165
+ fail(`more than ${maxNodes} elements and attributes`);
166
+ 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
+ }
171
+ }
172
+ while (/\s/.test(xml.charAt(position)))
173
+ position++;
174
+ const selfClosing = xml.startsWith('/>', position);
175
+ if (!selfClosing && xml.charAt(position) !== '>')
176
+ fail(`malformed start tag ${name}`);
177
+ position += selfClosing ? 2 : 1;
178
+ const element = new XmlElement(localNameOf(name), attributes ?? noAttributes);
179
+ const parent = stack.at(-1);
180
+ if (parent)
181
+ parent.children.push(element);
182
+ else if (root)
183
+ fail('a second root element');
184
+ else
185
+ root = element;
186
+ if (!selfClosing)
187
+ stack.push(element);
188
+ }
189
+ }
190
+ if (stack.length > 0)
191
+ fail(`unclosed element ${stack.at(-1).localName}`);
192
+ return root ?? fail('no root element');
193
+ }
194
+ //# sourceMappingURL=xml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml.js","sourceRoot":"","sources":["../../src/util/xml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { AccountDataStatus, type Account } from '../core/account.js';
2
+ import { Balance } from '../core/balance.js';
3
+ /**
4
+ * The account extension of the user parameter data (HIUPD "Erweiterung, kontobezogen", Formals E.3.1): JSON with the
5
+ * BIC, the balance, and what the bank tells about the data it holds for the account.
6
+ */
7
+ export declare class AccountExtension {
8
+ /** The BIC of the account, which spares the SEPA account list (Formals F.3.4). */
9
+ readonly bic: string | undefined;
10
+ /** What the bank tells about the account's data. */
11
+ readonly status: AccountDataStatus;
12
+ private readonly balance;
13
+ /** Whether `balance` holds all a balance query would deliver (`BalComplete`). */
14
+ private readonly balanceComplete;
15
+ private constructor();
16
+ /**
17
+ * Reads `json`; `undefined` if it is not a JSON object or any element is malformed, which voids the whole extension
18
+ * (Formals F.2, KF3).
19
+ */
20
+ static tryParse(json: string): AccountExtension | undefined;
21
+ private static read;
22
+ /** The balance of `account`, where the extension holds all a balance query would deliver (Formals F.3.2). */
23
+ completeBalance(account: Account): Balance | undefined;
24
+ }
25
+ //# sourceMappingURL=account-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-extension.d.ts","sourceRoot":"","sources":["../../src/v3/account-extension.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAyB7C;;;GAGG;AACH,qBAAa,gBAAgB;IAEzB,kFAAkF;IAClF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAChC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,eAAe;IAPlC,OAAO;IAUP;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAU3D,OAAO,CAAC,MAAM,CAAC,IAAI;IAgBnB,6GAA6G;IAC7G,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;CAkBvD"}
@@ -0,0 +1,173 @@
1
+ // Internal to the package, and named after the FinTS specification. Documentation is where the meaning is not evident.
2
+ import { AccountDataStatus } from '../core/account.js';
3
+ import { Amount, withMark } from '../core/amount.js';
4
+ import { Balance } from '../core/balance.js';
5
+ import { parseFintsDate, parseUtcPlusOneDateTime } from '../util/dates.js';
6
+ import { fail, FormatError } from '../util/errors.js';
7
+ import { isJsonObject } from '../util/json.js';
8
+ import { nonBlank } from '../util/text.js';
9
+ /**
10
+ * The account extension of the user parameter data (HIUPD "Erweiterung, kontobezogen", Formals E.3.1): JSON with the
11
+ * BIC, the balance, and what the bank tells about the data it holds for the account.
12
+ */
13
+ export class AccountExtension {
14
+ bic;
15
+ status;
16
+ balance;
17
+ balanceComplete;
18
+ constructor(
19
+ /** The BIC of the account, which spares the SEPA account list (Formals F.3.4). */
20
+ bic,
21
+ /** What the bank tells about the account's data. */
22
+ status, balance,
23
+ /** Whether `balance` holds all a balance query would deliver (`BalComplete`). */
24
+ balanceComplete) {
25
+ this.bic = bic;
26
+ this.status = status;
27
+ this.balance = balance;
28
+ this.balanceComplete = balanceComplete;
29
+ }
30
+ /**
31
+ * Reads `json`; `undefined` if it is not a JSON object or any element is malformed, which voids the whole extension
32
+ * (Formals F.2, KF3).
33
+ */
34
+ static tryParse(json) {
35
+ try {
36
+ const decoded = JSON.parse(json);
37
+ return isJsonObject(decoded) ? AccountExtension.read(new Json(decoded)) : undefined;
38
+ }
39
+ catch (error) {
40
+ if (error instanceof FormatError || error instanceof SyntaxError)
41
+ return undefined;
42
+ throw error;
43
+ }
44
+ }
45
+ static read(json) {
46
+ const balance = json.object('AcctBal');
47
+ const next = json.object('AcctStatNext');
48
+ return new AccountExtension(json.string('BIC'), new AccountDataStatus({
49
+ inventory: json.object('Inventory')?.strings ?? new Map(),
50
+ lastTransactions: json.string('umsltzt'),
51
+ nextTransactionsAt: next === undefined ? undefined : moment(next, '000000'),
52
+ transactionBalancesCurrent: json.flag('BalStatAcct') || json.flag('BalStatAct'),
53
+ }), balance === undefined ? undefined : readBalance(balance), json.flag('BalComplete'));
54
+ }
55
+ /** The balance of `account`, where the extension holds all a balance query would deliver (Formals F.3.2). */
56
+ completeBalance(account) {
57
+ const b = this.balance;
58
+ if (b === undefined || !this.balanceComplete)
59
+ return undefined;
60
+ return new Balance({
61
+ account,
62
+ productName: account.productName,
63
+ booked: b.booked.amount,
64
+ bookedAsOf: b.booked.date,
65
+ bookedAsOfTime: b.booked.time,
66
+ pending: b.pending?.amount,
67
+ creditLine: b.creditLine,
68
+ available: b.available,
69
+ used: b.used,
70
+ overdraft: b.overdraft,
71
+ bookingDate: b.bookingDate,
72
+ bookingTime: b.bookingTime,
73
+ });
74
+ }
75
+ }
76
+ function readBalance(json) {
77
+ const currency = json.string('Cur') ?? fail('Extension balance without currency');
78
+ const amount = (key) => {
79
+ const value = json.string(key);
80
+ return value === undefined ? undefined : Amount.parseDecimal(value, currency);
81
+ };
82
+ const saldo = (key) => {
83
+ const s = json.object(key);
84
+ if (s === undefined)
85
+ return undefined;
86
+ const value = s.string('Val') ?? fail('Extension balance without value');
87
+ return {
88
+ amount: withMark(Amount.parseDecimal(value, currency), s.string('DebCrd'), 'C', 'D'),
89
+ date: parseFintsDate(s.string('Date')) ?? fail('Extension balance without date'),
90
+ time: moment(s),
91
+ };
92
+ };
93
+ const bookTime = json.object('BookTime');
94
+ return {
95
+ booked: saldo('CurValBal') ?? fail('Extension balance without booked balance'),
96
+ pending: saldo('InclPendTransBal'),
97
+ creditLine: amount('OverdraftLim'),
98
+ available: amount('AvailFunds'),
99
+ used: amount('AlrdyDrwnOnBal'),
100
+ overdraft: amount('OverDraft'),
101
+ bookingDate: bookTime === undefined ? undefined : parseFintsDate(bookTime.string('Date')),
102
+ bookingTime: bookTime === undefined ? undefined : moment(bookTime),
103
+ };
104
+ }
105
+ /**
106
+ * The moment of `Date` and `Time` in `json`, which the extension states in UTC+01:00 all year round; `undefined`
107
+ * without a time, unless `defaultTime` stands in for it.
108
+ */
109
+ function moment(json, defaultTime) {
110
+ const time = json.string('Time') ?? defaultTime;
111
+ if (time === undefined)
112
+ return undefined;
113
+ return parseUtcPlusOneDateTime(json.string('Date'), time) ?? fail('Extension date or time is malformed');
114
+ }
115
+ /**
116
+ * A JSON object of the extension, read by key without regard to case: the specification itself spells some keys
117
+ * differently (`OverDraftLim` and `OverdraftLim`). Values of the wrong type are a `FormatError`.
118
+ */
119
+ class Json {
120
+ values = new Map();
121
+ constructor(values) {
122
+ for (const [key, value] of Object.entries(values))
123
+ this.values.set(key.toLowerCase(), value);
124
+ }
125
+ value(key) {
126
+ return this.values.get(key.toLowerCase());
127
+ }
128
+ /** A string, or a number written as string: dates and times come as either. */
129
+ string(key) {
130
+ const value = this.value(key);
131
+ if (value === undefined || value === null)
132
+ return undefined;
133
+ if (typeof value === 'string')
134
+ return nonBlank(value);
135
+ if (typeof value === 'number')
136
+ return String(value);
137
+ throw new FormatError(`Extension element "${key}" is not text`);
138
+ }
139
+ flag(key) {
140
+ const value = this.value(key);
141
+ if (value === undefined || value === null)
142
+ return false;
143
+ if (typeof value === 'boolean')
144
+ return value;
145
+ if (typeof value === 'string')
146
+ return value === 'J' || value.toLowerCase() === 'true';
147
+ throw new FormatError(`Extension element "${key}" is not a flag`);
148
+ }
149
+ object(key) {
150
+ const value = this.value(key);
151
+ if (value === undefined || value === null)
152
+ return undefined;
153
+ if (isJsonObject(value))
154
+ return new Json(value);
155
+ throw new FormatError(`Extension element "${key}" is not an object`);
156
+ }
157
+ /** The object's values as strings, keyed in capitals, as segment IDs are written. */
158
+ get strings() {
159
+ const result = new Map();
160
+ for (const [key, value] of this.values) {
161
+ if (value === null)
162
+ result.set(key.toUpperCase(), '');
163
+ else if (typeof value === 'string')
164
+ result.set(key.toUpperCase(), value);
165
+ else if (typeof value === 'number')
166
+ result.set(key.toUpperCase(), String(value));
167
+ else
168
+ throw new FormatError(`Extension element "${key}" is not text`);
169
+ }
170
+ return result;
171
+ }
172
+ }
173
+ //# sourceMappingURL=account-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-extension.js","sourceRoot":"","sources":["../../src/v3/account-extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { MessageDirection, MessageLogger } from '../core/client.js';
2
+ import { type FinTsTransport } from '../core/transport.js';
3
+ /**
4
+ * Throws `FinTsProtocolError` if a message of `size` bytes exceeds the bank's `limit` in kilobytes (1024 bytes): the
5
+ * specification does not allow to send such a message.
6
+ */
7
+ export declare function checkMessageSize(size: number, limit: number | undefined): void;
8
+ /** The bank's FinTS endpoint: posts messages there and reports them to the logger. */
9
+ export declare class BankConnection {
10
+ private readonly logger;
11
+ private readonly transport;
12
+ /** Where the messages go, as `FinTsConfig` checked it. */
13
+ private readonly href;
14
+ /** Aborts the requests on their way (`abortRequests`). */
15
+ private requests;
16
+ /** A connection to `url` through `transport`, an `HttpTransport` by default. */
17
+ constructor(url: URL, transport: FinTsTransport | undefined, logger: MessageLogger | undefined);
18
+ /**
19
+ * Posts `body` to a new copy of the URL, so that a transport that changes the one it is given changes no later
20
+ * request.
21
+ *
22
+ * Reports any failure of the transport as `FinTsTransportError`: a custom transport that calls `fetch` fails with a
23
+ * `TypeError` where the network does, and one that throws another `FinTsError`, such as `FinTsPinError`, would pass
24
+ * for an answer of the bank. Of such an error only the message is kept (`failureMessage`), since it may hold `body`,
25
+ * as the errors of HTTP clients such as axios do.
26
+ */
27
+ post(body: Uint8Array, contentType: string): Promise<Uint8Array>;
28
+ /** Reports a message to the logger; `message` is only built when a logger is set. */
29
+ 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;
32
+ close(): void;
33
+ }
34
+ //# sourceMappingURL=bank-connection.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,58 @@
1
+ import { FinTsProtocolError, FinTsTransportError } from '../core/errors.js';
2
+ import { failureMessage, HttpTransport } from '../core/transport.js';
3
+ /**
4
+ * Throws `FinTsProtocolError` if a message of `size` bytes exceeds the bank's `limit` in kilobytes (1024 bytes): the
5
+ * specification does not allow to send such a message.
6
+ */
7
+ export function checkMessageSize(size, limit) {
8
+ if (limit !== undefined && limit > 0 && size > limit * 1024) {
9
+ throw new FinTsProtocolError(`A message of ${size} bytes exceeds the bank's maximum message size of ${limit} KB`);
10
+ }
11
+ }
12
+ /** The bank's FinTS endpoint: posts messages there and reports them to the logger. */
13
+ export class BankConnection {
14
+ logger;
15
+ transport;
16
+ /** Where the messages go, as `FinTsConfig` checked it. */
17
+ href;
18
+ /** Aborts the requests on their way (`abortRequests`). */
19
+ requests = new AbortController();
20
+ /** A connection to `url` through `transport`, an `HttpTransport` by default. */
21
+ constructor(url, transport, logger) {
22
+ this.logger = logger;
23
+ this.href = url.href;
24
+ this.transport = transport ?? new HttpTransport();
25
+ }
26
+ /**
27
+ * Posts `body` to a new copy of the URL, so that a transport that changes the one it is given changes no later
28
+ * request.
29
+ *
30
+ * Reports any failure of the transport as `FinTsTransportError`: a custom transport that calls `fetch` fails with a
31
+ * `TypeError` where the network does, and one that throws another `FinTsError`, such as `FinTsPinError`, would pass
32
+ * for an answer of the bank. Of such an error only the message is kept (`failureMessage`), since it may hold `body`,
33
+ * as the errors of HTTP clients such as axios do.
34
+ */
35
+ async post(body, contentType) {
36
+ try {
37
+ return await this.transport.post(new URL(this.href), body, contentType, this.requests.signal);
38
+ }
39
+ catch (error) {
40
+ if (error instanceof FinTsTransportError)
41
+ throw error;
42
+ throw new FinTsTransportError(failureMessage(error));
43
+ }
44
+ }
45
+ /** Reports a message to the logger; `message` is only built when a logger is set. */
46
+ log(direction, message) {
47
+ this.logger?.(direction, message());
48
+ }
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();
53
+ }
54
+ close() {
55
+ this.transport.close();
56
+ }
57
+ }
58
+ //# sourceMappingURL=bank-connection.js.map
@@ -0,0 +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"}
@@ -0,0 +1,112 @@
1
+ import { TanChallenge } from '../tan/challenge.js';
2
+ import { TanMethod } from '../tan/tan-models.js';
3
+ import { IncomingMessage3 } from './message.js';
4
+ import type { FinTs3Protocol } from './protocol.js';
5
+ import type { SegmentSpec } from './syntax.js';
6
+ /** The bank's request to approve a message with a TAN or in a banking app; `R` is the bank's answer. */
7
+ export interface Approval<R> {
8
+ /** What the user is asked. */
9
+ readonly challenge: TanChallenge;
10
+ /** Sends the TAN the user entered. */
11
+ readonly submitTan: (tan: string) => Promise<R>;
12
+ /** Asks the bank whether the user has approved in the banking app. */
13
+ readonly checkStatus: () => Promise<R>;
14
+ /**
15
+ * Whether the bank announces a push message for once the user has approved (return code 3957), before which the
16
+ * status must not be asked. The client has no push channel, so the user reports the approval instead.
17
+ */
18
+ readonly waitForPush: boolean;
19
+ /** The new instructions a status answer gives the user (return code 3956); `undefined` where it gives none. */
20
+ readonly instructionsIn: (response: R) => string | undefined;
21
+ }
22
+ /**
23
+ * One FinTS 3.0 dialog: numbered messages under the dialog ID the bank assigns in its first answer, signed with a TAN
24
+ * method and medium, and the approvals the bank asks for. The `FinTs3Protocol` builds the messages and signs them.
25
+ */
26
+ export declare class FinTs3Dialog {
27
+ private readonly protocol;
28
+ readonly method: TanMethod;
29
+ /** The TAN medium the messages name, where the method takes one. */
30
+ readonly tanMedium: string | undefined;
31
+ private readonly anonymous;
32
+ private systemId;
33
+ private id;
34
+ private messageNumber;
35
+ private ended;
36
+ /** When the bank last answered without rejecting the whole message, which shows it still knows the dialog. */
37
+ private lastAnswer;
38
+ private constructor();
39
+ static signed(protocol: FinTs3Protocol, method: TanMethod, tanMedium?: string): FinTs3Dialog;
40
+ /** A dialog without login, which only delivers the bank parameter data. */
41
+ static anonymous(protocol: FinTs3Protocol): FinTs3Dialog;
42
+ /** Whether the bank knows this dialog and it has not ended. */
43
+ get isActive(): boolean;
44
+ /**
45
+ * Whether the dialog has ended, on either side.
46
+ *
47
+ * The bank ends a dialog idle for longer than its maximum timeout (HIBPA, Formals C.9), or five minutes where it
48
+ * states none. Such a dialog is neither used nor ended again: the bank would refuse any message in it.
49
+ */
50
+ private get hasEnded();
51
+ private get idleTooLong();
52
+ /** Whether the messages are signed with a two-step TAN method, so that the bank may ask for approvals. */
53
+ private get isTwoStep();
54
+ /** The version of the HKTAN segments: that of the HITANS segment the bank describes the method in. */
55
+ private get tanVersion();
56
+ /** Opens the dialog; with `synchronize` the bank also assigns a customer system ID. */
57
+ start(synchronize?: boolean): Promise<IncomingMessage3>;
58
+ /**
59
+ * The messages that open the dialog and send `order` while no TAN medium is chosen yet, as for listing the media:
60
+ * `login` opens the dialog, asking strong authentication for `order` with a two-step method, and `order` sends the
61
+ * order in a message of its own.
62
+ */
63
+ startWith(order: SegmentSpec): {
64
+ readonly login: () => Promise<IncomingMessage3>;
65
+ readonly order: () => Promise<IncomingMessage3>;
66
+ };
67
+ /**
68
+ * Opens the anonymous dialog; the answer carries the bank parameter data.
69
+ *
70
+ * With `announceSca` the message also carries HKTAN, the way a client that can do strong customer authentication
71
+ * tells the bank so, whereupon the bank may send parameter data suited to it (PIN/TAN, B.4.3.1).
72
+ */
73
+ requestBankParameters(announceSca?: boolean): Promise<IncomingMessage3>;
74
+ /** Sends `order`, asking for strong customer authentication where the bank requires it. */
75
+ send(order: SegmentSpec): Promise<IncomingMessage3>;
76
+ /**
77
+ * Ends the dialog at the bank and returns the answer; `undefined` if the dialog is not active or the end failed.
78
+ *
79
+ * Bank and connection errors are ignored, since the bank may have ended the dialog on its side already.
80
+ */
81
+ end(): Promise<IncomingMessage3 | undefined>;
82
+ /** Forgets the dialog without contacting the bank, for example after the bank rejected the PIN. */
83
+ discard(): void;
84
+ /**
85
+ * The approval `response`, the dialog's latest answer, asks for with return code 0030 (TAN) or 3955 (banking app):
86
+ * HITAN of process 4, answered with HKTAN process 2 (TAN) or S (status); `undefined` if it asks for none, or carries
87
+ * only the dummy challenge of a message the bank exempts from strong authentication.
88
+ *
89
+ * The bank has not executed the message then, so a request without a challenge is a `FinTsProtocolError`: read as
90
+ * done, it would report an empty result. So is an app approval with a method of HITANS #6: the status request
91
+ * (process S) came with version 7, along with app approvals (PIN/TAN B.5.2).
92
+ */
93
+ approvalAskedIn(response: IncomingMessage3): Approval<IncomingMessage3> | undefined;
94
+ private tanRequest;
95
+ /**
96
+ * Sends `segments`, with `tan` where they complete an approval, as the next message, and reads the bank's answer. The
97
+ * message counts once the bank has answered, whatever it answered.
98
+ *
99
+ * The bank assigns the dialog ID in its answer to the first message, so the answer to another user's first message
100
+ * passes for it (`ParameterStore.reportedUpdVersion`). Any other answer to another message fails with
101
+ * `FinTsProtocolError` before anything of it is kept: a relay or proxy that mixes up answers would hand the client
102
+ * another user's data, or a page of another query.
103
+ *
104
+ * The dialog ends on the client's side, without a dialog end, where it is over for the bank: after a return code that
105
+ * ends it, such as 9800, and after a rejected opening message (Formals C.1.2), or a broken connection (C.6).
106
+ *
107
+ * Only an answer that does not reject the whole message starts the idle time anew (`hasEnded`): a rejection may come
108
+ * from a bank that has ended the dialog without saying so.
109
+ */
110
+ private sendSegments;
111
+ }
112
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/v3/dialog.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB/C,wGAAwG;AACxG,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IAEjC,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAEhD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B,+GAA+G;IAC/G,QAAQ,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;CAC9D;AAED;;;GAGG;AACH,qBAAa,YAAY;IAUrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAb5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAS;IAEtB,8GAA8G;IAC9G,OAAO,CAAC,UAAU,CAAqB;IAEvC,OAAO;IAUP,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY;IAI5F,2EAA2E;IAC3E,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY;IAIxD,+DAA+D;IAC/D,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;OAKG;IACH,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,WAAW,GAMtB;IAED,0GAA0G;IAC1G,OAAO,KAAK,SAAS,GAEpB;IAED,sGAAsG;IACtG,OAAO,KAAK,UAAU,GAErB;IAED,uFAAuF;IACvF,KAAK,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IASrD;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG;QAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;KACjD;IAWD;;;;;OAKG;IACH,qBAAqB,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAOrE,2FAA2F;IAC3F,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAMnD;;;;OAIG;IACG,GAAG,IAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAWlD,mGAAmG;IACnG,OAAO,IAAI,IAAI;IAIf;;;;;;;;OAQG;IACH,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,SAAS;IA8BnF,OAAO,CAAC,UAAU;IASlB;;;;;;;;;;;;;;OAcG;YACW,YAAY;CA4B3B"}