@ksefnik/core 0.0.1

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 (238) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bank/auto-detect.d.ts +3 -0
  3. package/dist/bank/auto-detect.d.ts.map +1 -0
  4. package/dist/bank/auto-detect.js +29 -0
  5. package/dist/bank/auto-detect.js.map +1 -0
  6. package/dist/bank/index.d.ts +10 -0
  7. package/dist/bank/index.d.ts.map +1 -0
  8. package/dist/bank/index.js +20 -0
  9. package/dist/bank/index.js.map +1 -0
  10. package/dist/bank/nip-extractor.d.ts +3 -0
  11. package/dist/bank/nip-extractor.d.ts.map +1 -0
  12. package/dist/bank/nip-extractor.js +36 -0
  13. package/dist/bank/nip-extractor.js.map +1 -0
  14. package/dist/bank/parsers/csv-base.d.ts +4 -0
  15. package/dist/bank/parsers/csv-base.d.ts.map +1 -0
  16. package/dist/bank/parsers/csv-base.js +48 -0
  17. package/dist/bank/parsers/csv-base.js.map +1 -0
  18. package/dist/bank/parsers/index.d.ts +8 -0
  19. package/dist/bank/parsers/index.d.ts.map +1 -0
  20. package/dist/bank/parsers/index.js +21 -0
  21. package/dist/bank/parsers/index.js.map +1 -0
  22. package/dist/bank/parsers/ing.parser.d.ts +7 -0
  23. package/dist/bank/parsers/ing.parser.d.ts.map +1 -0
  24. package/dist/bank/parsers/ing.parser.js +43 -0
  25. package/dist/bank/parsers/ing.parser.js.map +1 -0
  26. package/dist/bank/parsers/mbank.parser.d.ts +7 -0
  27. package/dist/bank/parsers/mbank.parser.d.ts.map +1 -0
  28. package/dist/bank/parsers/mbank.parser.js +39 -0
  29. package/dist/bank/parsers/mbank.parser.js.map +1 -0
  30. package/dist/bank/parsers/mt940.parser.d.ts +7 -0
  31. package/dist/bank/parsers/mt940.parser.d.ts.map +1 -0
  32. package/dist/bank/parsers/mt940.parser.js +57 -0
  33. package/dist/bank/parsers/mt940.parser.js.map +1 -0
  34. package/dist/bank/parsers/pko.parser.d.ts +7 -0
  35. package/dist/bank/parsers/pko.parser.d.ts.map +1 -0
  36. package/dist/bank/parsers/pko.parser.js +38 -0
  37. package/dist/bank/parsers/pko.parser.js.map +1 -0
  38. package/dist/bank/parsers/santander.parser.d.ts +7 -0
  39. package/dist/bank/parsers/santander.parser.d.ts.map +1 -0
  40. package/dist/bank/parsers/santander.parser.js +46 -0
  41. package/dist/bank/parsers/santander.parser.js.map +1 -0
  42. package/dist/index.d.ts +16 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +18 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/ksef/cache.d.ts +12 -0
  47. package/dist/ksef/cache.d.ts.map +1 -0
  48. package/dist/ksef/cache.js +36 -0
  49. package/dist/ksef/cache.js.map +1 -0
  50. package/dist/ksef/index.d.ts +6 -0
  51. package/dist/ksef/index.d.ts.map +1 -0
  52. package/dist/ksef/index.js +5 -0
  53. package/dist/ksef/index.js.map +1 -0
  54. package/dist/ksef/ksef.adapter.d.ts +16 -0
  55. package/dist/ksef/ksef.adapter.d.ts.map +1 -0
  56. package/dist/ksef/ksef.adapter.js +81 -0
  57. package/dist/ksef/ksef.adapter.js.map +1 -0
  58. package/dist/ksef/retry.d.ts +7 -0
  59. package/dist/ksef/retry.d.ts.map +1 -0
  60. package/dist/ksef/retry.js +41 -0
  61. package/dist/ksef/retry.js.map +1 -0
  62. package/dist/ksef/session.d.ts +16 -0
  63. package/dist/ksef/session.d.ts.map +1 -0
  64. package/dist/ksef/session.js +39 -0
  65. package/dist/ksef/session.js.map +1 -0
  66. package/dist/ksef/types.d.ts +56 -0
  67. package/dist/ksef/types.d.ts.map +1 -0
  68. package/dist/ksef/types.js +2 -0
  69. package/dist/ksef/types.js.map +1 -0
  70. package/dist/ksefnik.d.ts +51 -0
  71. package/dist/ksefnik.d.ts.map +1 -0
  72. package/dist/ksefnik.js +104 -0
  73. package/dist/ksefnik.js.map +1 -0
  74. package/dist/matching/context.d.ts +5 -0
  75. package/dist/matching/context.d.ts.map +1 -0
  76. package/dist/matching/context.js +19 -0
  77. package/dist/matching/context.js.map +1 -0
  78. package/dist/matching/index.d.ts +6 -0
  79. package/dist/matching/index.d.ts.map +1 -0
  80. package/dist/matching/index.js +6 -0
  81. package/dist/matching/index.js.map +1 -0
  82. package/dist/matching/passes/exact.pass.d.ts +3 -0
  83. package/dist/matching/passes/exact.pass.d.ts.map +1 -0
  84. package/dist/matching/passes/exact.pass.js +34 -0
  85. package/dist/matching/passes/exact.pass.js.map +1 -0
  86. package/dist/matching/passes/fuzzy.pass.d.ts +3 -0
  87. package/dist/matching/passes/fuzzy.pass.d.ts.map +1 -0
  88. package/dist/matching/passes/fuzzy.pass.js +40 -0
  89. package/dist/matching/passes/fuzzy.pass.js.map +1 -0
  90. package/dist/matching/passes/index.d.ts +9 -0
  91. package/dist/matching/passes/index.d.ts.map +1 -0
  92. package/dist/matching/passes/index.js +21 -0
  93. package/dist/matching/passes/index.js.map +1 -0
  94. package/dist/matching/passes/invoice-ref.pass.d.ts +3 -0
  95. package/dist/matching/passes/invoice-ref.pass.d.ts.map +1 -0
  96. package/dist/matching/passes/invoice-ref.pass.js +32 -0
  97. package/dist/matching/passes/invoice-ref.pass.js.map +1 -0
  98. package/dist/matching/passes/ksef-ref.pass.d.ts +3 -0
  99. package/dist/matching/passes/ksef-ref.pass.d.ts.map +1 -0
  100. package/dist/matching/passes/ksef-ref.pass.js +25 -0
  101. package/dist/matching/passes/ksef-ref.pass.js.map +1 -0
  102. package/dist/matching/passes/partial.pass.d.ts +3 -0
  103. package/dist/matching/passes/partial.pass.d.ts.map +1 -0
  104. package/dist/matching/passes/partial.pass.js +55 -0
  105. package/dist/matching/passes/partial.pass.js.map +1 -0
  106. package/dist/matching/passes/proximity.pass.d.ts +3 -0
  107. package/dist/matching/passes/proximity.pass.d.ts.map +1 -0
  108. package/dist/matching/passes/proximity.pass.js +49 -0
  109. package/dist/matching/passes/proximity.pass.js.map +1 -0
  110. package/dist/matching/pipeline.d.ts +3 -0
  111. package/dist/matching/pipeline.d.ts.map +1 -0
  112. package/dist/matching/pipeline.js +76 -0
  113. package/dist/matching/pipeline.js.map +1 -0
  114. package/dist/matching/scoring.d.ts +5 -0
  115. package/dist/matching/scoring.d.ts.map +1 -0
  116. package/dist/matching/scoring.js +28 -0
  117. package/dist/matching/scoring.js.map +1 -0
  118. package/dist/plugins/index.d.ts +3 -0
  119. package/dist/plugins/index.d.ts.map +1 -0
  120. package/dist/plugins/index.js +3 -0
  121. package/dist/plugins/index.js.map +1 -0
  122. package/dist/plugins/loader.d.ts +3 -0
  123. package/dist/plugins/loader.d.ts.map +1 -0
  124. package/dist/plugins/loader.js +13 -0
  125. package/dist/plugins/loader.js.map +1 -0
  126. package/dist/plugins/registry.d.ts +8 -0
  127. package/dist/plugins/registry.d.ts.map +1 -0
  128. package/dist/plugins/registry.js +15 -0
  129. package/dist/plugins/registry.js.map +1 -0
  130. package/dist/storage/in-memory.storage.d.ts +13 -0
  131. package/dist/storage/in-memory.storage.d.ts.map +1 -0
  132. package/dist/storage/in-memory.storage.js +57 -0
  133. package/dist/storage/in-memory.storage.js.map +1 -0
  134. package/dist/storage/index.d.ts +3 -0
  135. package/dist/storage/index.d.ts.map +1 -0
  136. package/dist/storage/index.js +3 -0
  137. package/dist/storage/index.js.map +1 -0
  138. package/dist/storage/sqlite.storage.d.ts +13 -0
  139. package/dist/storage/sqlite.storage.d.ts.map +1 -0
  140. package/dist/storage/sqlite.storage.js +225 -0
  141. package/dist/storage/sqlite.storage.js.map +1 -0
  142. package/dist/validation/engine.d.ts +10 -0
  143. package/dist/validation/engine.d.ts.map +1 -0
  144. package/dist/validation/engine.js +19 -0
  145. package/dist/validation/engine.js.map +1 -0
  146. package/dist/validation/index.d.ts +6 -0
  147. package/dist/validation/index.d.ts.map +1 -0
  148. package/dist/validation/index.js +4 -0
  149. package/dist/validation/index.js.map +1 -0
  150. package/dist/validation/rule.d.ts +17 -0
  151. package/dist/validation/rule.d.ts.map +1 -0
  152. package/dist/validation/rule.js +2 -0
  153. package/dist/validation/rule.js.map +1 -0
  154. package/dist/validation/rules/amount-max.d.ts +3 -0
  155. package/dist/validation/rules/amount-max.d.ts.map +1 -0
  156. package/dist/validation/rules/amount-max.js +14 -0
  157. package/dist/validation/rules/amount-max.js.map +1 -0
  158. package/dist/validation/rules/amount-positive.d.ts +3 -0
  159. package/dist/validation/rules/amount-positive.d.ts.map +1 -0
  160. package/dist/validation/rules/amount-positive.js +13 -0
  161. package/dist/validation/rules/amount-positive.js.map +1 -0
  162. package/dist/validation/rules/buyer-nip-format.d.ts +3 -0
  163. package/dist/validation/rules/buyer-nip-format.d.ts.map +1 -0
  164. package/dist/validation/rules/buyer-nip-format.js +16 -0
  165. package/dist/validation/rules/buyer-nip-format.js.map +1 -0
  166. package/dist/validation/rules/currency-valid.d.ts +3 -0
  167. package/dist/validation/rules/currency-valid.d.ts.map +1 -0
  168. package/dist/validation/rules/currency-valid.js +13 -0
  169. package/dist/validation/rules/currency-valid.js.map +1 -0
  170. package/dist/validation/rules/date-not-future.d.ts +3 -0
  171. package/dist/validation/rules/date-not-future.d.ts.map +1 -0
  172. package/dist/validation/rules/date-not-future.js +18 -0
  173. package/dist/validation/rules/date-not-future.js.map +1 -0
  174. package/dist/validation/rules/date-order.d.ts +3 -0
  175. package/dist/validation/rules/date-order.d.ts.map +1 -0
  176. package/dist/validation/rules/date-order.js +15 -0
  177. package/dist/validation/rules/date-order.js.map +1 -0
  178. package/dist/validation/rules/date-range.d.ts +3 -0
  179. package/dist/validation/rules/date-range.d.ts.map +1 -0
  180. package/dist/validation/rules/date-range.js +18 -0
  181. package/dist/validation/rules/date-range.js.map +1 -0
  182. package/dist/validation/rules/date-valid.d.ts +3 -0
  183. package/dist/validation/rules/date-valid.d.ts.map +1 -0
  184. package/dist/validation/rules/date-valid.js +15 -0
  185. package/dist/validation/rules/date-valid.js.map +1 -0
  186. package/dist/validation/rules/description-length.d.ts +3 -0
  187. package/dist/validation/rules/description-length.d.ts.map +1 -0
  188. package/dist/validation/rules/description-length.js +19 -0
  189. package/dist/validation/rules/description-length.js.map +1 -0
  190. package/dist/validation/rules/duplicate-check.d.ts +3 -0
  191. package/dist/validation/rules/duplicate-check.d.ts.map +1 -0
  192. package/dist/validation/rules/duplicate-check.js +17 -0
  193. package/dist/validation/rules/duplicate-check.js.map +1 -0
  194. package/dist/validation/rules/index.d.ts +24 -0
  195. package/dist/validation/rules/index.d.ts.map +1 -0
  196. package/dist/validation/rules/index.js +44 -0
  197. package/dist/validation/rules/index.js.map +1 -0
  198. package/dist/validation/rules/invoice-number-format.d.ts +3 -0
  199. package/dist/validation/rules/invoice-number-format.d.ts.map +1 -0
  200. package/dist/validation/rules/invoice-number-format.js +14 -0
  201. package/dist/validation/rules/invoice-number-format.js.map +1 -0
  202. package/dist/validation/rules/ksef-reference-format.d.ts +3 -0
  203. package/dist/validation/rules/ksef-reference-format.d.ts.map +1 -0
  204. package/dist/validation/rules/ksef-reference-format.js +18 -0
  205. package/dist/validation/rules/ksef-reference-format.js.map +1 -0
  206. package/dist/validation/rules/line-items-sum.d.ts +3 -0
  207. package/dist/validation/rules/line-items-sum.d.ts.map +1 -0
  208. package/dist/validation/rules/line-items-sum.js +17 -0
  209. package/dist/validation/rules/line-items-sum.js.map +1 -0
  210. package/dist/validation/rules/nip-format.d.ts +3 -0
  211. package/dist/validation/rules/nip-format.d.ts.map +1 -0
  212. package/dist/validation/rules/nip-format.js +14 -0
  213. package/dist/validation/rules/nip-format.js.map +1 -0
  214. package/dist/validation/rules/nip-not-zeros.d.ts +3 -0
  215. package/dist/validation/rules/nip-not-zeros.d.ts.map +1 -0
  216. package/dist/validation/rules/nip-not-zeros.js +12 -0
  217. package/dist/validation/rules/nip-not-zeros.js.map +1 -0
  218. package/dist/validation/rules/quantity-positive.d.ts +3 -0
  219. package/dist/validation/rules/quantity-positive.d.ts.map +1 -0
  220. package/dist/validation/rules/quantity-positive.js +21 -0
  221. package/dist/validation/rules/quantity-positive.js.map +1 -0
  222. package/dist/validation/rules/required-fields.d.ts +3 -0
  223. package/dist/validation/rules/required-fields.d.ts.map +1 -0
  224. package/dist/validation/rules/required-fields.js +18 -0
  225. package/dist/validation/rules/required-fields.js.map +1 -0
  226. package/dist/validation/rules/seller-buyer-different.d.ts +3 -0
  227. package/dist/validation/rules/seller-buyer-different.d.ts.map +1 -0
  228. package/dist/validation/rules/seller-buyer-different.js +15 -0
  229. package/dist/validation/rules/seller-buyer-different.js.map +1 -0
  230. package/dist/validation/rules/vat-calculation.d.ts +3 -0
  231. package/dist/validation/rules/vat-calculation.d.ts.map +1 -0
  232. package/dist/validation/rules/vat-calculation.js +19 -0
  233. package/dist/validation/rules/vat-calculation.js.map +1 -0
  234. package/dist/validation/rules/vat-rate-valid.d.ts +3 -0
  235. package/dist/validation/rules/vat-rate-valid.d.ts.map +1 -0
  236. package/dist/validation/rules/vat-rate-valid.js +22 -0
  237. package/dist/validation/rules/vat-rate-valid.js.map +1 -0
  238. package/package.json +44 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CodeFormers-it
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ export type BankFormat = 'mt940' | 'mbank' | 'ing' | 'pko' | 'santander';
2
+ export declare function detectBankFormat(content: string): BankFormat | null;
3
+ //# sourceMappingURL=auto-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-detect.d.ts","sourceRoot":"","sources":["../../src/bank/auto-detect.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,CAAA;AAExE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAiCnE"}
@@ -0,0 +1,29 @@
1
+ export function detectBankFormat(content) {
2
+ // MT940: starts with SWIFT message tags or contains MT940 fields
3
+ if (content.includes(':20:') && (content.includes(':60F:') || content.includes(':61:'))) {
4
+ return 'mt940';
5
+ }
6
+ if (content.startsWith('{1:')) {
7
+ return 'mt940';
8
+ }
9
+ // CSV detection: check first few lines for header patterns
10
+ const firstLines = content.slice(0, 2000);
11
+ // mBank: headers start with #
12
+ if (firstLines.includes('#Data operacji') && firstLines.includes('#Opis operacji')) {
13
+ return 'mbank';
14
+ }
15
+ // ING: quoted headers with specific columns
16
+ if (firstLines.includes('"Data transakcji"') && firstLines.includes('"Dane kontrahenta"')) {
17
+ return 'ing';
18
+ }
19
+ // PKO BP: comma-separated with specific headers
20
+ if (firstLines.includes('"Data operacji"') && firstLines.includes('"Typ transakcji"')) {
21
+ return 'pko';
22
+ }
23
+ // Santander: unquoted headers with specific pattern
24
+ if (firstLines.includes('Data operacji;Data waluty;Tytu') && firstLines.includes('Nadawca/Odbiorca')) {
25
+ return 'santander';
26
+ }
27
+ return null;
28
+ }
29
+ //# sourceMappingURL=auto-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-detect.js","sourceRoot":"","sources":["../../src/bank/auto-detect.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,iEAAiE;IACjE,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACxF,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,2DAA2D;IAC3D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IAEzC,8BAA8B;IAC9B,IAAI,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACnF,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,4CAA4C;IAC5C,IAAI,UAAU,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC1F,OAAO,KAAK,CAAA;IACd,CAAC;IAED,gDAAgD;IAChD,IAAI,UAAU,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtF,OAAO,KAAK,CAAA;IACd,CAAC;IAED,oDAAoD;IACpD,IAAI,UAAU,CAAC,QAAQ,CAAC,gCAAgC,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACrG,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { BankTransaction, BankStatementParser } from '@ksefnik/shared';
2
+ export { extractNIPs, extractFirstNIP } from './nip-extractor.js';
3
+ export { detectBankFormat } from './auto-detect.js';
4
+ export * from './parsers/index.js';
5
+ export interface ImportBankStatementOpts {
6
+ parsers?: BankStatementParser[];
7
+ }
8
+ export declare function importBankStatement(filePath: string, opts?: ImportBankStatementOpts): Promise<BankTransaction[]>;
9
+ export declare function importBankStatementFromString(content: string, opts?: ImportBankStatementOpts): Promise<BankTransaction[]>;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bank/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAI3E,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,cAAc,oBAAoB,CAAA;AAElC,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAA;CAChC;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAG5B;AAED,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,uBAAuB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAU5B"}
@@ -0,0 +1,20 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { UnsupportedBankFormatError } from '@ksefnik/shared';
3
+ import { getDefaultParsers } from './parsers/index.js';
4
+ export { extractNIPs, extractFirstNIP } from './nip-extractor.js';
5
+ export { detectBankFormat } from './auto-detect.js';
6
+ export * from './parsers/index.js';
7
+ export async function importBankStatement(filePath, opts) {
8
+ const content = readFileSync(filePath, 'utf-8');
9
+ return importBankStatementFromString(content, opts);
10
+ }
11
+ export async function importBankStatementFromString(content, opts) {
12
+ const parsers = opts?.parsers ?? getDefaultParsers();
13
+ for (const parser of parsers) {
14
+ if (await parser.canParse(content)) {
15
+ return parser.parse(content);
16
+ }
17
+ }
18
+ throw new UnsupportedBankFormatError('unknown');
19
+ }
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bank/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,cAAc,oBAAoB,CAAA;AAMlC,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,IAA8B;IAE9B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC/C,OAAO,6BAA6B,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAe,EACf,IAA8B;IAE9B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,iBAAiB,EAAE,CAAA;IAEpD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,IAAI,0BAA0B,CAAC,SAAS,CAAC,CAAA;AACjD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function extractNIPs(text: string): string[];
2
+ export declare function extractFirstNIP(text: string): string | undefined;
3
+ //# sourceMappingURL=nip-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nip-extractor.d.ts","sourceRoot":"","sources":["../../src/bank/nip-extractor.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BlD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhE"}
@@ -0,0 +1,36 @@
1
+ import { isValidNIP } from '@ksefnik/shared';
2
+ const MPP_PATTERN = /\/NIP\/(\d{10})\//;
3
+ const IDC_PATTERN = /\/IDC\/(\d{10})\//;
4
+ const PREFIXED_PATTERN = /NIP[:\s]*(\d{10})/gi;
5
+ const RAW_10_DIGIT = /\b(\d{10})\b/g;
6
+ export function extractNIPs(text) {
7
+ const found = new Set();
8
+ // Strategy 1: MPP structured
9
+ const mppMatch = text.match(MPP_PATTERN);
10
+ if (mppMatch?.[1]) {
11
+ found.add(mppMatch[1]);
12
+ }
13
+ const idcMatch = text.match(IDC_PATTERN);
14
+ if (idcMatch?.[1]) {
15
+ found.add(idcMatch[1]);
16
+ }
17
+ // Strategy 2: Prefixed (NIP: or NIP followed by digits)
18
+ let prefixMatch;
19
+ while ((prefixMatch = PREFIXED_PATTERN.exec(text)) !== null) {
20
+ if (prefixMatch[1]) {
21
+ found.add(prefixMatch[1]);
22
+ }
23
+ }
24
+ // Strategy 3: Raw 10-digit with valid checksum
25
+ let rawMatch;
26
+ while ((rawMatch = RAW_10_DIGIT.exec(text)) !== null) {
27
+ if (rawMatch[1] && isValidNIP(rawMatch[1])) {
28
+ found.add(rawMatch[1]);
29
+ }
30
+ }
31
+ return [...found];
32
+ }
33
+ export function extractFirstNIP(text) {
34
+ return extractNIPs(text)[0];
35
+ }
36
+ //# sourceMappingURL=nip-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nip-extractor.js","sourceRoot":"","sources":["../../src/bank/nip-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,MAAM,WAAW,GAAG,mBAAmB,CAAA;AACvC,MAAM,WAAW,GAAG,mBAAmB,CAAA;AACvC,MAAM,gBAAgB,GAAG,qBAAqB,CAAA;AAC9C,MAAM,YAAY,GAAG,eAAe,CAAA;AAEpC,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;IAE/B,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACxC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IACxB,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACxC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IACxB,CAAC;IAED,wDAAwD;IACxD,IAAI,WAAmC,CAAA;IACvC,OAAO,CAAC,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5D,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,QAAgC,CAAA;IACpC,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACrD,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function parseCSV(content: string, delimiter?: string): string[][];
2
+ export declare function stripBOM(content: string): string;
3
+ export declare function parseAmount(text: string): number;
4
+ //# sourceMappingURL=csv-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-base.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/csv-base.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,EAAE,EAAE,CAG7E;AAkCD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD"}
@@ -0,0 +1,48 @@
1
+ export function parseCSV(content, delimiter = ';') {
2
+ const lines = content.split(/\r?\n/).filter((l) => l.trim().length > 0);
3
+ return lines.map((line) => parseCsvLine(line, delimiter));
4
+ }
5
+ function parseCsvLine(line, delimiter) {
6
+ const fields = [];
7
+ let current = '';
8
+ let inQuotes = false;
9
+ for (let i = 0; i < line.length; i++) {
10
+ const char = line[i];
11
+ if (inQuotes) {
12
+ if (char === '"' && line[i + 1] === '"') {
13
+ current += '"';
14
+ i++;
15
+ }
16
+ else if (char === '"') {
17
+ inQuotes = false;
18
+ }
19
+ else {
20
+ current += char;
21
+ }
22
+ }
23
+ else {
24
+ if (char === '"') {
25
+ inQuotes = true;
26
+ }
27
+ else if (char === delimiter) {
28
+ fields.push(current.trim());
29
+ current = '';
30
+ }
31
+ else {
32
+ current += char;
33
+ }
34
+ }
35
+ }
36
+ fields.push(current.trim());
37
+ return fields;
38
+ }
39
+ export function stripBOM(content) {
40
+ return content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
41
+ }
42
+ export function parseAmount(text) {
43
+ // Handle both "1230,00" and "1230.00" and "+1230,00" / "-1230,00"
44
+ const cleaned = text.replace(/\s/g, '').replace(',', '.');
45
+ const num = parseFloat(cleaned);
46
+ return Math.round(num * 100);
47
+ }
48
+ //# sourceMappingURL=csv-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-base.js","sourceRoot":"","sources":["../../../src/bank/parsers/csv-base.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,YAAoB,GAAG;IAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACvE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,SAAiB;IACnD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,CAAA;QACrB,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxC,OAAO,IAAI,GAAG,CAAA;gBACd,CAAC,EAAE,CAAA;YACL,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,QAAQ,GAAG,KAAK,CAAA;YAClB,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,IAAI,CAAA;YACjB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,QAAQ,GAAG,IAAI,CAAA;YACjB,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;gBAC3B,OAAO,GAAG,EAAE,CAAA;YACd,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,IAAI,CAAA;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IAE3B,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACtE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,kEAAkE;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACzD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { BankStatementParser } from '@ksefnik/shared';
2
+ export { Mt940Parser } from './mt940.parser.js';
3
+ export { MbankParser } from './mbank.parser.js';
4
+ export { IngParser } from './ing.parser.js';
5
+ export { PkoParser } from './pko.parser.js';
6
+ export { SantanderParser } from './santander.parser.js';
7
+ export declare function getDefaultParsers(): BankStatementParser[];
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAO1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAUvD,wBAAgB,iBAAiB,IAAI,mBAAmB,EAAE,CAEzD"}
@@ -0,0 +1,21 @@
1
+ import { Mt940Parser } from './mt940.parser.js';
2
+ import { MbankParser } from './mbank.parser.js';
3
+ import { IngParser } from './ing.parser.js';
4
+ import { PkoParser } from './pko.parser.js';
5
+ import { SantanderParser } from './santander.parser.js';
6
+ export { Mt940Parser } from './mt940.parser.js';
7
+ export { MbankParser } from './mbank.parser.js';
8
+ export { IngParser } from './ing.parser.js';
9
+ export { PkoParser } from './pko.parser.js';
10
+ export { SantanderParser } from './santander.parser.js';
11
+ const defaultParsers = [
12
+ new Mt940Parser(),
13
+ new MbankParser(),
14
+ new IngParser(),
15
+ new PkoParser(),
16
+ new SantanderParser(),
17
+ ];
18
+ export function getDefaultParsers() {
19
+ return defaultParsers;
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bank/parsers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,MAAM,cAAc,GAA0B;IAC5C,IAAI,WAAW,EAAE;IACjB,IAAI,WAAW,EAAE;IACjB,IAAI,SAAS,EAAE;IACf,IAAI,SAAS,EAAE;IACf,IAAI,eAAe,EAAE;CACtB,CAAA;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,CAAA;AACvB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { BankStatementParser, BankTransaction } from '@ksefnik/shared';
2
+ export declare class IngParser implements BankStatementParser {
3
+ bank: string;
4
+ canParse(content: string | Buffer): Promise<boolean>;
5
+ parse(content: string | Buffer): Promise<BankTransaction[]>;
6
+ }
7
+ //# sourceMappingURL=ing.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ing.parser.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/ing.parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAS3E,qBAAa,SAAU,YAAW,mBAAmB;IACnD,IAAI,SAAQ;IAEN,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAiClE"}
@@ -0,0 +1,43 @@
1
+ import { parseCSV, stripBOM, parseAmount } from './csv-base.js';
2
+ import { extractFirstNIP } from '../nip-extractor.js';
3
+ function formatIngDate(yyyymmdd) {
4
+ // ING format: 20260301 -> 2026-03-01
5
+ return `${yyyymmdd.slice(0, 4)}-${yyyymmdd.slice(4, 6)}-${yyyymmdd.slice(6, 8)}`;
6
+ }
7
+ export class IngParser {
8
+ bank = 'ing';
9
+ async canParse(content) {
10
+ const text = typeof content === 'string' ? content : content.toString('utf-8');
11
+ return text.includes('"Data transakcji"') && text.includes('"Dane kontrahenta"');
12
+ }
13
+ async parse(content) {
14
+ const text = stripBOM(typeof content === 'string' ? content : content.toString('utf-8'));
15
+ const rows = parseCSV(text, ';');
16
+ const dataRows = rows.slice(1);
17
+ const transactions = [];
18
+ for (const row of dataRows) {
19
+ const [dateRaw, , counterparty, title, , , details, , amountStr] = row;
20
+ if (!dateRaw || !amountStr)
21
+ continue;
22
+ const date = formatIngDate(dateRaw);
23
+ const amount = parseAmount(amountStr);
24
+ const isOutgoing = amount < 0;
25
+ const description = title ?? '';
26
+ const nip = extractFirstNIP(`${counterparty ?? ''} ${details ?? ''} ${description}`);
27
+ transactions.push({
28
+ id: crypto.randomUUID(),
29
+ date,
30
+ amount,
31
+ description,
32
+ ...(isOutgoing
33
+ ? { recipientName: counterparty?.split(' UL ')[0]?.split(' ul ')[0], recipientNIP: nip }
34
+ : { senderName: counterparty?.split(' UL ')[0]?.split(' ul ')[0], senderNIP: nip }),
35
+ bank: 'ing',
36
+ raw: row.join(';'),
37
+ createdAt: new Date().toISOString(),
38
+ });
39
+ }
40
+ return transactions;
41
+ }
42
+ }
43
+ //# sourceMappingURL=ing.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ing.parser.js","sourceRoot":"","sources":["../../../src/bank/parsers/ing.parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,SAAS,aAAa,CAAC,QAAgB;IACrC,qCAAqC;IACrC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;AAClF,CAAC;AAED,MAAM,OAAO,SAAS;IACpB,IAAI,GAAG,KAAK,CAAA;IAEZ,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9E,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAA;IAClF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAwB;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QACxF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC9B,MAAM,YAAY,GAAsB,EAAE,CAAA;QAE1C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,OAAO,EAAE,AAAD,EAAG,YAAY,EAAE,KAAK,EAAE,AAAD,EAAG,AAAD,EAAG,OAAO,EAAE,AAAD,EAAG,SAAS,CAAC,GAAG,GAAG,CAAA;YACtE,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS;gBAAE,SAAQ;YAEpC,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;YACnC,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAA;YAC7B,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE,CAAA;YAC/B,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,YAAY,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,CAAA;YAEpF,YAAY,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;gBACvB,IAAI;gBACJ,MAAM;gBACN,WAAW;gBACX,GAAG,CAAC,UAAU;oBACZ,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE;oBACxF,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;gBACrF,IAAI,EAAE,KAAK;gBACX,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { BankStatementParser, BankTransaction } from '@ksefnik/shared';
2
+ export declare class MbankParser implements BankStatementParser {
3
+ bank: string;
4
+ canParse(content: string | Buffer): Promise<boolean>;
5
+ parse(content: string | Buffer): Promise<BankTransaction[]>;
6
+ }
7
+ //# sourceMappingURL=mbank.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mbank.parser.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/mbank.parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAI3E,qBAAa,WAAY,YAAW,mBAAmB;IACrD,IAAI,SAAU;IAER,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAiClE"}
@@ -0,0 +1,39 @@
1
+ import { parseCSV, stripBOM, parseAmount } from './csv-base.js';
2
+ import { extractFirstNIP } from '../nip-extractor.js';
3
+ export class MbankParser {
4
+ bank = 'mbank';
5
+ async canParse(content) {
6
+ const text = typeof content === 'string' ? content : content.toString('utf-8');
7
+ return text.includes('#Data operacji') && text.includes('#Opis operacji');
8
+ }
9
+ async parse(content) {
10
+ const text = stripBOM(typeof content === 'string' ? content : content.toString('utf-8'));
11
+ const rows = parseCSV(text, ';');
12
+ // Skip header row
13
+ const dataRows = rows.slice(1);
14
+ const transactions = [];
15
+ for (const row of dataRows) {
16
+ const [date, , operationType, title, counterparty, accountNumber, amountStr] = row;
17
+ if (!date || !amountStr)
18
+ continue;
19
+ const amount = parseAmount(amountStr);
20
+ const isOutgoing = amount < 0;
21
+ const description = title ?? '';
22
+ const nip = extractFirstNIP(`${counterparty ?? ''} ${description}`);
23
+ transactions.push({
24
+ id: crypto.randomUUID(),
25
+ date,
26
+ amount,
27
+ description,
28
+ ...(isOutgoing
29
+ ? { recipientName: counterparty, recipientNIP: nip }
30
+ : { senderName: counterparty, senderNIP: nip }),
31
+ bank: 'mbank',
32
+ raw: row.join(';'),
33
+ createdAt: new Date().toISOString(),
34
+ });
35
+ }
36
+ return transactions;
37
+ }
38
+ }
39
+ //# sourceMappingURL=mbank.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mbank.parser.js","sourceRoot":"","sources":["../../../src/bank/parsers/mbank.parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,MAAM,OAAO,WAAW;IACtB,IAAI,GAAG,OAAO,CAAA;IAEd,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9E,OAAO,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAC3E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAwB;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QACxF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAEhC,kBAAkB;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC9B,MAAM,YAAY,GAAsB,EAAE,CAAA;QAE1C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,EAAE,AAAD,EAAG,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,CAAC,GAAG,GAAG,CAAA;YAClF,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;gBAAE,SAAQ;YAEjC,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAA;YAC7B,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE,CAAA;YAC/B,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,YAAY,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,CAAA;YAEnE,YAAY,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;gBACvB,IAAI;gBACJ,MAAM;gBACN,WAAW;gBACX,GAAG,CAAC,UAAU;oBACZ,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,EAAE;oBACpD,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;gBACjD,IAAI,EAAE,OAAO;gBACb,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { BankStatementParser, BankTransaction } from '@ksefnik/shared';
2
+ export declare class Mt940Parser implements BankStatementParser {
3
+ bank: string;
4
+ canParse(content: string | Buffer): Promise<boolean>;
5
+ parse(content: string | Buffer): Promise<BankTransaction[]>;
6
+ }
7
+ //# sourceMappingURL=mt940.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mt940.parser.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/mt940.parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAgB3E,qBAAa,WAAY,YAAW,mBAAmB;IACrD,IAAI,SAAU;IAER,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMpD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CA+BlE"}
@@ -0,0 +1,57 @@
1
+ import { Parser as Mt940JsParser } from 'mt940js';
2
+ import { extractFirstNIP } from '../nip-extractor.js';
3
+ function createMt940JsParser() {
4
+ return new Mt940JsParser();
5
+ }
6
+ function formatDate(d) {
7
+ return d.toISOString().slice(0, 10);
8
+ }
9
+ function amountToGrosze(amount) {
10
+ return Math.round(amount * 100);
11
+ }
12
+ export class Mt940Parser {
13
+ bank = 'mt940';
14
+ async canParse(content) {
15
+ const text = typeof content === 'string' ? content : content.toString('utf-8');
16
+ return (text.includes(':20:') && (text.includes(':60F:') || text.includes(':61:'))) ||
17
+ text.startsWith('{1:');
18
+ }
19
+ async parse(content) {
20
+ const text = typeof content === 'string' ? content : content.toString('utf-8');
21
+ const parser = createMt940JsParser();
22
+ const statements = parser.parse(text);
23
+ const transactions = [];
24
+ for (const statement of statements) {
25
+ for (const tx of statement.transactions) {
26
+ const details = tx.details ?? '';
27
+ const nip = extractFirstNIP(details);
28
+ const isOutgoing = tx.amount < 0;
29
+ transactions.push({
30
+ id: crypto.randomUUID(),
31
+ date: formatDate(tx.date),
32
+ amount: amountToGrosze(tx.amount),
33
+ description: details,
34
+ ...(isOutgoing
35
+ ? { recipientNIP: nip, recipientName: extractName(details) }
36
+ : { senderNIP: nip, senderName: extractName(details) }),
37
+ bank: 'mt940',
38
+ raw: details,
39
+ createdAt: new Date().toISOString(),
40
+ });
41
+ }
42
+ }
43
+ return transactions;
44
+ }
45
+ }
46
+ function extractName(details) {
47
+ // MT940 field 86 subfield ~27 contains beneficiary name
48
+ const match = details.match(/~27([^~]+)/);
49
+ if (match?.[1])
50
+ return match[1].trim();
51
+ // fallback: try to find name after ~32
52
+ const match32 = details.match(/~32([^~]+)/);
53
+ if (match32?.[1])
54
+ return match32[1].trim();
55
+ return undefined;
56
+ }
57
+ //# sourceMappingURL=mt940.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mt940.parser.js","sourceRoot":"","sources":["../../../src/bank/parsers/mt940.parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,SAAS,mBAAmB;IAC1B,OAAO,IAAI,aAAa,EAAE,CAAA;AAC5B,CAAC;AAED,SAAS,UAAU,CAAC,CAAO;IACzB,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,OAAO,WAAW;IACtB,IAAI,GAAG,OAAO,CAAA;IAEd,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9E,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACjF,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAwB;QAClC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9E,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAA;QACpC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAErC,MAAM,YAAY,GAAsB,EAAE,CAAA;QAE1C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;gBACxC,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,IAAI,EAAE,CAAA;gBAChC,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;gBAEpC,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;gBAEhC,YAAY,CAAC,IAAI,CAAC;oBAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;oBACvB,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC;oBACzB,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC,MAAM,CAAC;oBACjC,WAAW,EAAE,OAAO;oBACpB,GAAG,CAAC,UAAU;wBACZ,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE;wBAC5D,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;oBACzD,IAAI,EAAE,OAAO;oBACb,GAAG,EAAE,OAAO;oBACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;CACF;AAED,SAAS,WAAW,CAAC,OAAe;IAClC,wDAAwD;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAEtC,uCAAuC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC3C,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAE1C,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { BankStatementParser, BankTransaction } from '@ksefnik/shared';
2
+ export declare class PkoParser implements BankStatementParser {
3
+ bank: string;
4
+ canParse(content: string | Buffer): Promise<boolean>;
5
+ parse(content: string | Buffer): Promise<BankTransaction[]>;
6
+ }
7
+ //# sourceMappingURL=pko.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pko.parser.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/pko.parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAI3E,qBAAa,SAAU,YAAW,mBAAmB;IACnD,IAAI,SAAQ;IAEN,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAgClE"}
@@ -0,0 +1,38 @@
1
+ import { parseCSV, stripBOM, parseAmount } from './csv-base.js';
2
+ import { extractFirstNIP } from '../nip-extractor.js';
3
+ export class PkoParser {
4
+ bank = 'pko';
5
+ async canParse(content) {
6
+ const text = typeof content === 'string' ? content : content.toString('utf-8');
7
+ return text.includes('"Data operacji"') && text.includes('"Typ transakcji"');
8
+ }
9
+ async parse(content) {
10
+ const text = stripBOM(typeof content === 'string' ? content : content.toString('utf-8'));
11
+ const rows = parseCSV(text, ',');
12
+ const dataRows = rows.slice(1);
13
+ const transactions = [];
14
+ for (const row of dataRows) {
15
+ const [date, , , amountStr, , , counterparty, title, nipRaw] = row;
16
+ if (!date || !amountStr)
17
+ continue;
18
+ const amount = parseAmount(amountStr);
19
+ const isOutgoing = amount < 0;
20
+ const description = title ?? '';
21
+ const nip = nipRaw?.match(/^\d{10}$/)?.[0] ?? extractFirstNIP(`${counterparty ?? ''} ${description}`);
22
+ transactions.push({
23
+ id: crypto.randomUUID(),
24
+ date,
25
+ amount,
26
+ description,
27
+ ...(isOutgoing
28
+ ? { recipientName: counterparty, recipientNIP: nip }
29
+ : { senderName: counterparty, senderNIP: nip }),
30
+ bank: 'pko',
31
+ raw: row.join(','),
32
+ createdAt: new Date().toISOString(),
33
+ });
34
+ }
35
+ return transactions;
36
+ }
37
+ }
38
+ //# sourceMappingURL=pko.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pko.parser.js","sourceRoot":"","sources":["../../../src/bank/parsers/pko.parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,MAAM,OAAO,SAAS;IACpB,IAAI,GAAG,KAAK,CAAA;IAEZ,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9E,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAA;IAC9E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAwB;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QACxF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC9B,MAAM,YAAY,GAAsB,EAAE,CAAA;QAE1C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,EAAE,AAAD,EAAG,AAAD,EAAG,SAAS,EAAE,AAAD,EAAG,AAAD,EAAG,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAA;YAClE,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;gBAAE,SAAQ;YAEjC,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAA;YAC7B,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE,CAAA;YAC/B,MAAM,GAAG,GAAG,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,GAAG,YAAY,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,CAAA;YAErG,YAAY,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;gBACvB,IAAI;gBACJ,MAAM;gBACN,WAAW;gBACX,GAAG,CAAC,UAAU;oBACZ,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,EAAE;oBACpD,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;gBACjD,IAAI,EAAE,KAAK;gBACX,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { BankStatementParser, BankTransaction } from '@ksefnik/shared';
2
+ export declare class SantanderParser implements BankStatementParser {
3
+ bank: string;
4
+ canParse(content: string | Buffer): Promise<boolean>;
5
+ parse(content: string | Buffer): Promise<BankTransaction[]>;
6
+ }
7
+ //# sourceMappingURL=santander.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"santander.parser.d.ts","sourceRoot":"","sources":["../../../src/bank/parsers/santander.parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAU3E,qBAAa,eAAgB,YAAW,mBAAmB;IACzD,IAAI,SAAc;IAEZ,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAoClE"}
@@ -0,0 +1,46 @@
1
+ import { parseCSV, stripBOM, parseAmount } from './csv-base.js';
2
+ import { extractFirstNIP } from '../nip-extractor.js';
3
+ function formatSantanderDate(ddmmyyyy) {
4
+ // Santander format: 01-03-2026 -> 2026-03-01
5
+ const [dd, mm, yyyy] = ddmmyyyy.split('-');
6
+ return `${yyyy}-${mm}-${dd}`;
7
+ }
8
+ export class SantanderParser {
9
+ bank = 'santander';
10
+ async canParse(content) {
11
+ const text = typeof content === 'string' ? content : content.toString('utf-8');
12
+ return text.includes('Data operacji;Data waluty;Tytu') && text.includes('Nadawca/Odbiorca');
13
+ }
14
+ async parse(content) {
15
+ const text = stripBOM(typeof content === 'string' ? content : content.toString('utf-8'));
16
+ const rows = parseCSV(text, ';');
17
+ const dataRows = rows.slice(1);
18
+ const transactions = [];
19
+ for (const row of dataRows) {
20
+ const [dateRaw, , title, counterparty, , amountStr] = row;
21
+ if (!dateRaw || !amountStr)
22
+ continue;
23
+ const date = formatSantanderDate(dateRaw);
24
+ const amount = parseAmount(amountStr);
25
+ const isOutgoing = amount < 0;
26
+ const description = title ?? '';
27
+ const nip = extractFirstNIP(`${counterparty ?? ''} ${description}`);
28
+ // Santander puts "FIRMA NIP: 1234567890" in counterparty field
29
+ const cleanName = counterparty?.replace(/\s*NIP:\s*\d{10}/, '').trim();
30
+ transactions.push({
31
+ id: crypto.randomUUID(),
32
+ date,
33
+ amount,
34
+ description,
35
+ ...(isOutgoing
36
+ ? { recipientName: cleanName, recipientNIP: nip }
37
+ : { senderName: cleanName, senderNIP: nip }),
38
+ bank: 'santander',
39
+ raw: row.join(';'),
40
+ createdAt: new Date().toISOString(),
41
+ });
42
+ }
43
+ return transactions;
44
+ }
45
+ }
46
+ //# sourceMappingURL=santander.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"santander.parser.js","sourceRoot":"","sources":["../../../src/bank/parsers/santander.parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,SAAS,mBAAmB,CAAC,QAAgB;IAC3C,6CAA6C;IAC7C,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1C,OAAO,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,CAAA;AAC9B,CAAC;AAED,MAAM,OAAO,eAAe;IAC1B,IAAI,GAAG,WAAW,CAAA;IAElB,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9E,OAAO,IAAI,CAAC,QAAQ,CAAC,gCAAgC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAA;IAC7F,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAwB;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QACxF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC9B,MAAM,YAAY,GAAsB,EAAE,CAAA;QAE1C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,OAAO,EAAE,AAAD,EAAG,KAAK,EAAE,YAAY,EAAE,AAAD,EAAG,SAAS,CAAC,GAAG,GAAG,CAAA;YACzD,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS;gBAAE,SAAQ;YAEpC,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;YACzC,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAA;YAC7B,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE,CAAA;YAC/B,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,YAAY,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,CAAA;YAEnE,+DAA+D;YAC/D,MAAM,SAAS,GAAG,YAAY,EAAE,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;YAEtE,YAAY,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;gBACvB,IAAI;gBACJ,MAAM;gBACN,WAAW;gBACX,GAAG,CAAC,UAAU;oBACZ,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE;oBACjD,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;gBAC9C,IAAI,EAAE,WAAW;gBACjB,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,YAAY,CAAA;IACrB,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ export { Ksefnik, createKsefnik } from './ksefnik.js';
2
+ export type { CreateKsefnikOpts } from './ksefnik.js';
3
+ export { InMemoryStorage, SqliteStorage } from './storage/index.js';
4
+ export { KsefAdapterImpl } from './ksef/index.js';
5
+ export { withRetry } from './ksef/index.js';
6
+ export { TtlCache, cacheKey } from './ksef/index.js';
7
+ export { SessionManager } from './ksef/index.js';
8
+ export type { KsefClient, KsefClientConfig, KsefSessionState, KsefRawInvoice } from './ksef/index.js';
9
+ export type { RetryOptions } from './ksef/index.js';
10
+ export type { SessionManagerOptions } from './ksef/index.js';
11
+ export { importBankStatement, importBankStatementFromString, extractNIPs, extractFirstNIP, detectBankFormat, Mt940Parser, MbankParser, IngParser, PkoParser, SantanderParser, getDefaultParsers, } from './bank/index.js';
12
+ export { validateInvoice, validateInvoices, allRules } from './validation/index.js';
13
+ export type { ValidationRule, ValidationResult, ValidationContext, ValidationReport } from './validation/index.js';
14
+ export { runPipeline, defaultPasses } from './matching/index.js';
15
+ export { PluginRegistry, loadPlugin } from './plugins/index.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAGrD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrG,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,eAAe,EACf,iBAAiB,GAClB,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACnF,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGlH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGhE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA"}