@actual-app/sync-server 25.5.0 → 25.6.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 (244) hide show
  1. package/{app.js → build/app.js} +4 -5
  2. package/build/bin/actual-server.js +101 -0
  3. package/build/migrations/1694360000000-create-folders.js +21 -0
  4. package/{migrations → build/migrations}/1694360479680-create-account-db.js +2 -4
  5. package/{migrations → build/migrations}/1694362247011-create-secret-table.js +2 -4
  6. package/build/migrations/1702667624000-rename-nordigen-secrets.js +9 -0
  7. package/{migrations → build/migrations}/1718889148000-openid.js +4 -10
  8. package/{migrations → build/migrations}/1719409568000-multiuser.js +10 -26
  9. package/build/src/account-db.js +182 -0
  10. package/build/src/accounts/openid.js +287 -0
  11. package/build/src/accounts/password.js +98 -0
  12. package/build/src/app-account.js +125 -0
  13. package/build/src/app-admin.js +317 -0
  14. package/build/src/app-admin.test.js +303 -0
  15. package/build/src/app-gocardless/app-gocardless.js +193 -0
  16. package/build/src/app-gocardless/bank-factory.js +84 -0
  17. package/build/src/app-gocardless/banks/abanca_caglesmm.js +17 -0
  18. package/build/src/app-gocardless/banks/abnamro_abnanl2a.js +37 -0
  19. package/build/src/app-gocardless/banks/american_express_aesudef1.js +32 -0
  20. package/build/src/app-gocardless/banks/bancsabadell_bsabesbbb.js +22 -0
  21. package/build/src/app-gocardless/banks/bank.interface.js +1 -0
  22. package/build/src/app-gocardless/banks/bank_of_ireland_b365_bofiie2d.js +25 -0
  23. package/build/src/app-gocardless/banks/bankinter_bkbkesmm.js +18 -0
  24. package/build/src/app-gocardless/banks/belfius_gkccbebb.js +13 -0
  25. package/build/src/app-gocardless/banks/berliner_sparkasse_beladebexxx.js +48 -0
  26. package/build/src/app-gocardless/banks/bnp_be_gebabebb.js +64 -0
  27. package/build/src/app-gocardless/banks/boursobank_bousfrppxxx.js +73 -0
  28. package/build/src/app-gocardless/banks/cbc_cregbebb.js +27 -0
  29. package/build/src/app-gocardless/banks/commerzbank_cobadeff.js +43 -0
  30. package/build/src/app-gocardless/banks/danskebank_dabno22.js +26 -0
  31. package/build/src/app-gocardless/banks/direkt_heladef1822.js +13 -0
  32. package/build/src/app-gocardless/banks/easybank_bawaatww.js +42 -0
  33. package/build/src/app-gocardless/banks/entercard_swednokk.js +28 -0
  34. package/build/src/app-gocardless/banks/fortuneo_ftnofrp1xxx.js +34 -0
  35. package/build/src/app-gocardless/banks/hype_hyeeit22.js +63 -0
  36. package/build/src/app-gocardless/banks/ing_ingbrobu.js +56 -0
  37. package/build/src/app-gocardless/banks/ing_ingddeff.js +34 -0
  38. package/build/src/app-gocardless/banks/ing_pl_ingbplpw.js +29 -0
  39. package/build/src/app-gocardless/banks/integration-bank.js +78 -0
  40. package/build/src/app-gocardless/banks/isybank_itbbitmm.js +13 -0
  41. package/build/src/app-gocardless/banks/kbc_kredbebb.js +26 -0
  42. package/build/src/app-gocardless/banks/lhv-lhvbee22.js +24 -0
  43. package/build/src/app-gocardless/banks/mbank_retail_brexplpw.js +41 -0
  44. package/build/src/app-gocardless/banks/nationwide_naiagb21.js +32 -0
  45. package/build/src/app-gocardless/banks/nbg_ethngraaxxx.js +39 -0
  46. package/build/src/app-gocardless/banks/norwegian_xx_norwnok1.js +61 -0
  47. package/build/src/app-gocardless/banks/revolut_revolt21.js +20 -0
  48. package/build/src/app-gocardless/banks/sandboxfinance_sfin0000.js +21 -0
  49. package/build/src/app-gocardless/banks/seb_kort_bank_ab.js +63 -0
  50. package/build/src/app-gocardless/banks/seb_privat.js +19 -0
  51. package/build/src/app-gocardless/banks/sparnord_spnodk22.js +19 -0
  52. package/build/src/app-gocardless/banks/spk_karlsruhe_karsde66.js +48 -0
  53. package/build/src/app-gocardless/banks/spk_marburg_biedenkopf_heladef1mar.js +25 -0
  54. package/build/src/app-gocardless/banks/spk_worms_alzey_ried_malade51wor.js +14 -0
  55. package/build/src/app-gocardless/banks/ssk_dusseldorf_dussdeddxxx.js +36 -0
  56. package/build/src/app-gocardless/banks/swedbank_habalv22.js +30 -0
  57. package/build/src/app-gocardless/banks/tests/abanca_caglesmm.spec.js +17 -0
  58. package/build/src/app-gocardless/banks/tests/abnamro_abnanl2a.spec.js +45 -0
  59. package/build/src/app-gocardless/banks/tests/bancsabadell_bsabesbbb.spec.js +41 -0
  60. package/build/src/app-gocardless/banks/tests/belfius_gkccbebb.spec.js +16 -0
  61. package/build/src/app-gocardless/banks/tests/boursobank_bousfrppxxx.spec.js +102 -0
  62. package/build/src/app-gocardless/banks/tests/cbc_cregbebb.spec.js +24 -0
  63. package/build/src/app-gocardless/banks/tests/commerzbank_cobadeff.spec.js +105 -0
  64. package/build/src/app-gocardless/banks/tests/easybank_bawaatww.spec.js +36 -0
  65. package/build/src/app-gocardless/banks/tests/fortuneo_ftnofrp1xxx.spec.js +159 -0
  66. package/build/src/app-gocardless/banks/tests/ing_ingddeff.spec.js +267 -0
  67. package/build/src/app-gocardless/banks/tests/ing_pl_ingbplpw.spec.js +186 -0
  68. package/build/src/app-gocardless/banks/tests/integration_bank.spec.js +127 -0
  69. package/build/src/app-gocardless/banks/tests/kbc_kredbebb.spec.js +24 -0
  70. package/build/src/app-gocardless/banks/tests/lhv-lhvbee22.spec.js +50 -0
  71. package/build/src/app-gocardless/banks/tests/mbank_retail_brexplpw.spec.js +156 -0
  72. package/build/src/app-gocardless/banks/tests/nationwide_naiagb21.spec.js +64 -0
  73. package/build/src/app-gocardless/banks/tests/nbg_ethngraaxxx.spec.js +36 -0
  74. package/build/src/app-gocardless/banks/tests/revolut_revolt21.spec.js +30 -0
  75. package/build/src/app-gocardless/banks/tests/sandboxfinance_sfin0000.spec.js +112 -0
  76. package/build/src/app-gocardless/banks/tests/spk_marburg_biedenkopf_heladef1mar.spec.js +214 -0
  77. package/build/src/app-gocardless/banks/tests/ssk_dusseldorf_dussdeddxxx.spec.js +60 -0
  78. package/build/src/app-gocardless/banks/tests/swedbank_habalv22.spec.js +45 -0
  79. package/build/src/app-gocardless/banks/tests/virgin_nrnbgb22.spec.js +36 -0
  80. package/{src → build/src}/app-gocardless/banks/util/escape-regexp.js +1 -1
  81. package/{src → build/src}/app-gocardless/banks/util/extract-payeeName-from-remittanceInfo.js +11 -16
  82. package/build/src/app-gocardless/banks/virgin_nrnbgb22.js +31 -0
  83. package/build/src/app-gocardless/errors.js +67 -0
  84. package/build/src/app-gocardless/gocardless-node.types.js +1 -0
  85. package/build/src/app-gocardless/gocardless.types.js +1 -0
  86. package/build/src/app-gocardless/services/gocardless-service.js +504 -0
  87. package/build/src/app-gocardless/services/tests/fixtures.js +165 -0
  88. package/build/src/app-gocardless/services/tests/gocardless-service.spec.js +387 -0
  89. package/build/src/app-gocardless/tests/bank-factory.spec.js +13 -0
  90. package/build/src/app-gocardless/tests/utils.spec.js +158 -0
  91. package/build/src/app-gocardless/util/handle-error.js +15 -0
  92. package/build/src/app-gocardless/utils.js +41 -0
  93. package/build/src/app-openid.js +83 -0
  94. package/build/src/app-pluggyai/app-pluggyai.js +164 -0
  95. package/build/src/app-pluggyai/pluggyai-service.js +97 -0
  96. package/build/src/app-secrets.js +48 -0
  97. package/build/src/app-simplefin/app-simplefin.js +335 -0
  98. package/build/src/app-sync/errors.js +12 -0
  99. package/build/src/app-sync/services/files-service.js +158 -0
  100. package/build/src/app-sync/tests/services/files-service.test.js +192 -0
  101. package/build/src/app-sync/validation.js +65 -0
  102. package/build/src/app-sync.js +302 -0
  103. package/build/src/app-sync.test.js +655 -0
  104. package/build/src/app.js +138 -0
  105. package/build/src/config-types.js +1 -0
  106. package/build/src/db.js +50 -0
  107. package/build/src/load-config.js +274 -0
  108. package/build/src/migrations.js +23 -0
  109. package/build/src/scripts/disable-openid.js +31 -0
  110. package/build/src/scripts/enable-openid.js +36 -0
  111. package/build/src/scripts/health-check.js +16 -0
  112. package/build/src/scripts/reset-password.js +40 -0
  113. package/build/src/scripts/run-migrations.js +6 -0
  114. package/build/src/secrets.test.js +68 -0
  115. package/build/src/services/secrets-service.js +79 -0
  116. package/build/src/services/user-service.js +201 -0
  117. package/build/src/sync-simple.js +68 -0
  118. package/{src → build/src}/util/hash.js +1 -2
  119. package/build/src/util/middlewares.js +49 -0
  120. package/{src → build/src}/util/paths.js +3 -6
  121. package/build/src/util/payee-name.js +37 -0
  122. package/build/src/util/prompt.js +70 -0
  123. package/build/src/util/title/index.js +43 -0
  124. package/build/src/util/title/lower-case.js +90 -0
  125. package/build/src/util/title/specials.js +21 -0
  126. package/build/src/util/validate-user.js +55 -0
  127. package/package.json +32 -36
  128. package/bin/actual-server.js +0 -117
  129. package/migrations/1694360000000-create-folders.js +0 -25
  130. package/migrations/1702667624000-rename-nordigen-secrets.js +0 -19
  131. package/src/account-db.js +0 -239
  132. package/src/accounts/openid.js +0 -368
  133. package/src/accounts/password.js +0 -149
  134. package/src/app-account.js +0 -155
  135. package/src/app-admin.js +0 -410
  136. package/src/app-admin.test.js +0 -381
  137. package/src/app-gocardless/app-gocardless.js +0 -274
  138. package/src/app-gocardless/bank-factory.js +0 -91
  139. package/src/app-gocardless/banks/abanca_caglesmm.js +0 -22
  140. package/src/app-gocardless/banks/abnamro_abnanl2a.js +0 -57
  141. package/src/app-gocardless/banks/american_express_aesudef1.js +0 -40
  142. package/src/app-gocardless/banks/bancsabadell_bsabesbbb.js +0 -31
  143. package/src/app-gocardless/banks/bank.interface.ts +0 -51
  144. package/src/app-gocardless/banks/bank_of_ireland_b365_bofiie2d.js +0 -39
  145. package/src/app-gocardless/banks/bankinter_bkbkesmm.js +0 -24
  146. package/src/app-gocardless/banks/belfius_gkccbebb.js +0 -17
  147. package/src/app-gocardless/banks/berliner_sparkasse_beladebexxx.js +0 -61
  148. package/src/app-gocardless/banks/bnp_be_gebabebb.js +0 -73
  149. package/src/app-gocardless/banks/cbc_cregbebb.js +0 -34
  150. package/src/app-gocardless/banks/commerzbank_cobadeff.js +0 -54
  151. package/src/app-gocardless/banks/danskebank_dabno22.js +0 -39
  152. package/src/app-gocardless/banks/direkt_heladef1822.js +0 -18
  153. package/src/app-gocardless/banks/easybank_bawaatww.js +0 -50
  154. package/src/app-gocardless/banks/entercard_swednokk.js +0 -40
  155. package/src/app-gocardless/banks/fortuneo_ftnofrp1xxx.js +0 -46
  156. package/src/app-gocardless/banks/hype_hyeeit22.js +0 -74
  157. package/src/app-gocardless/banks/ing_ingbrobu.js +0 -70
  158. package/src/app-gocardless/banks/ing_ingddeff.js +0 -47
  159. package/src/app-gocardless/banks/ing_pl_ingbplpw.js +0 -46
  160. package/src/app-gocardless/banks/integration-bank.js +0 -115
  161. package/src/app-gocardless/banks/isybank_itbbitmm.js +0 -18
  162. package/src/app-gocardless/banks/kbc_kredbebb.js +0 -33
  163. package/src/app-gocardless/banks/lhv-lhvbee22.js +0 -36
  164. package/src/app-gocardless/banks/mbank_retail_brexplpw.js +0 -56
  165. package/src/app-gocardless/banks/nationwide_naiagb21.js +0 -46
  166. package/src/app-gocardless/banks/nbg_ethngraaxxx.js +0 -51
  167. package/src/app-gocardless/banks/norwegian_xx_norwnok1.js +0 -74
  168. package/src/app-gocardless/banks/revolut_revolt21.js +0 -37
  169. package/src/app-gocardless/banks/sandboxfinance_sfin0000.js +0 -28
  170. package/src/app-gocardless/banks/seb_kort_bank_ab.js +0 -59
  171. package/src/app-gocardless/banks/seb_privat.js +0 -29
  172. package/src/app-gocardless/banks/sparnord_spnodk22.js +0 -24
  173. package/src/app-gocardless/banks/spk_karlsruhe_karsde66.js +0 -61
  174. package/src/app-gocardless/banks/spk_marburg_biedenkopf_heladef1mar.js +0 -30
  175. package/src/app-gocardless/banks/spk_worms_alzey_ried_malade51wor.js +0 -19
  176. package/src/app-gocardless/banks/ssk_dusseldorf_dussdeddxxx.js +0 -50
  177. package/src/app-gocardless/banks/swedbank_habalv22.js +0 -47
  178. package/src/app-gocardless/banks/tests/abanca_caglesmm.spec.js +0 -21
  179. package/src/app-gocardless/banks/tests/abnamro_abnanl2a.spec.js +0 -61
  180. package/src/app-gocardless/banks/tests/bancsabadell_bsabesbbb.spec.js +0 -53
  181. package/src/app-gocardless/banks/tests/belfius_gkccbebb.spec.js +0 -22
  182. package/src/app-gocardless/banks/tests/cbc_cregbebb.spec.js +0 -34
  183. package/src/app-gocardless/banks/tests/commerzbank_cobadeff.spec.js +0 -133
  184. package/src/app-gocardless/banks/tests/easybank_bawaatww.spec.js +0 -54
  185. package/src/app-gocardless/banks/tests/fortuneo_ftnofrp1xxx.spec.js +0 -206
  186. package/src/app-gocardless/banks/tests/ing_ingddeff.spec.js +0 -302
  187. package/src/app-gocardless/banks/tests/ing_pl_ingbplpw.spec.js +0 -202
  188. package/src/app-gocardless/banks/tests/integration_bank.spec.js +0 -156
  189. package/src/app-gocardless/banks/tests/kbc_kredbebb.spec.js +0 -38
  190. package/src/app-gocardless/banks/tests/lhv-lhvbee22.spec.js +0 -68
  191. package/src/app-gocardless/banks/tests/mbank_retail_brexplpw.spec.js +0 -171
  192. package/src/app-gocardless/banks/tests/nationwide_naiagb21.spec.js +0 -105
  193. package/src/app-gocardless/banks/tests/nbg_ethngraaxxx.spec.js +0 -48
  194. package/src/app-gocardless/banks/tests/revolut_revolt21.spec.js +0 -42
  195. package/src/app-gocardless/banks/tests/sandboxfinance_sfin0000.spec.js +0 -133
  196. package/src/app-gocardless/banks/tests/spk_marburg_biedenkopf_heladef1mar.spec.js +0 -255
  197. package/src/app-gocardless/banks/tests/ssk_dusseldorf_dussdeddxxx.spec.js +0 -100
  198. package/src/app-gocardless/banks/tests/swedbank_habalv22.spec.js +0 -57
  199. package/src/app-gocardless/banks/tests/virgin_nrnbgb22.spec.js +0 -54
  200. package/src/app-gocardless/banks/virgin_nrnbgb22.js +0 -39
  201. package/src/app-gocardless/errors.js +0 -84
  202. package/src/app-gocardless/gocardless-node.types.ts +0 -497
  203. package/src/app-gocardless/gocardless.types.ts +0 -93
  204. package/src/app-gocardless/link.html +0 -18
  205. package/src/app-gocardless/services/gocardless-service.js +0 -620
  206. package/src/app-gocardless/services/tests/fixtures.js +0 -181
  207. package/src/app-gocardless/services/tests/gocardless-service.spec.js +0 -537
  208. package/src/app-gocardless/tests/bank-factory.spec.js +0 -20
  209. package/src/app-gocardless/tests/utils.spec.js +0 -162
  210. package/src/app-gocardless/util/handle-error.js +0 -16
  211. package/src/app-gocardless/utils.js +0 -45
  212. package/src/app-openid.js +0 -108
  213. package/src/app-pluggyai/app-pluggyai.js +0 -215
  214. package/src/app-pluggyai/pluggyai-service.js +0 -120
  215. package/src/app-secrets.js +0 -61
  216. package/src/app-simplefin/app-simplefin.js +0 -405
  217. package/src/app-sync/errors.js +0 -13
  218. package/src/app-sync/services/files-service.js +0 -243
  219. package/src/app-sync/tests/services/files-service.test.js +0 -247
  220. package/src/app-sync/validation.js +0 -77
  221. package/src/app-sync.js +0 -391
  222. package/src/app-sync.test.js +0 -877
  223. package/src/app.js +0 -149
  224. package/src/config-types.ts +0 -44
  225. package/src/db.js +0 -58
  226. package/src/load-config.js +0 -307
  227. package/src/migrations.js +0 -36
  228. package/src/run-migrations.js +0 -8
  229. package/src/scripts/disable-openid.js +0 -44
  230. package/src/scripts/enable-openid.js +0 -53
  231. package/src/scripts/health-check.js +0 -23
  232. package/src/scripts/reset-password.js +0 -51
  233. package/src/secrets.test.js +0 -83
  234. package/src/services/secrets-service.js +0 -94
  235. package/src/services/user-service.js +0 -272
  236. package/src/sync-simple.js +0 -95
  237. package/src/util/middlewares.js +0 -62
  238. package/src/util/payee-name.js +0 -45
  239. package/src/util/prompt.js +0 -88
  240. package/src/util/title/index.js +0 -59
  241. package/src/util/title/lower-case.js +0 -93
  242. package/src/util/title/specials.js +0 -21
  243. package/src/util/validate-user.js +0 -68
  244. /package/{src → build/src}/sql/messages.sql +0 -0
@@ -1,50 +0,0 @@
1
- import d from 'date-fns';
2
-
3
- import { formatPayeeName } from '../../util/payee-name.js';
4
- import { title } from '../../util/title/index.js';
5
-
6
- import Fallback from './integration-bank.js';
7
-
8
- /** @type {import('./bank.interface.js').IBank} */
9
- export default {
10
- ...Fallback,
11
-
12
- institutionIds: ['EASYBANK_BAWAATWW'],
13
-
14
- // If date is same, sort by transactionId
15
- sortTransactions: (transactions = []) =>
16
- transactions.sort((a, b) => {
17
- const diff =
18
- +new Date(b.valueDate || b.bookingDate) -
19
- +new Date(a.valueDate || a.bookingDate);
20
- if (diff !== 0) return diff;
21
- return parseInt(b.transactionId) - parseInt(a.transactionId);
22
- }),
23
-
24
- normalizeTransaction(transaction, booked) {
25
- const editedTrans = { ...transaction };
26
-
27
- let payeeName = formatPayeeName(transaction);
28
- if (!payeeName) payeeName = extractPayeeName(transaction);
29
- editedTrans.payeeName = payeeName;
30
-
31
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
32
- },
33
- };
34
-
35
- /**
36
- * Extracts the payee name from the remittanceInformationStructured
37
- * @param {import('../gocardless-node.types.js').Transaction} transaction
38
- */
39
- function extractPayeeName(transaction) {
40
- const structured = transaction.remittanceInformationStructured;
41
- // The payee name is betweeen the transaction timestamp (11.07. 11:36) and the location, that starts with \\
42
- const regex = /\d{2}\.\d{2}\. \d{2}:\d{2}(.*)\\\\/;
43
- const matches = structured.match(regex);
44
- if (matches && matches.length > 1 && matches[1]) {
45
- return title(matches[1]);
46
- } else {
47
- // As a fallback if still no payee is found, the whole information is used
48
- return structured;
49
- }
50
- }
@@ -1,40 +0,0 @@
1
- import { amountToInteger } from '../utils.js';
2
-
3
- import Fallback from './integration-bank.js';
4
-
5
- /** @type {import('./bank.interface.js').IBank} */
6
- export default {
7
- ...Fallback,
8
-
9
- institutionIds: ['ENTERCARD_SWEDNOKK'],
10
-
11
- normalizeTransaction(transaction, booked) {
12
- const editedTrans = { ...transaction };
13
-
14
- // GoCardless's Entercard integration returns forex transactions with the
15
- // foreign amount in `transactionAmount`, but at least the amount actually
16
- // billed to the account is now available in
17
- // `remittanceInformationUnstructured`.
18
- const remittanceInformationUnstructured =
19
- transaction.remittanceInformationUnstructured;
20
- if (remittanceInformationUnstructured.startsWith('billingAmount: ')) {
21
- transaction.transactionAmount = {
22
- amount: remittanceInformationUnstructured.substring(15),
23
- currency: 'SEK',
24
- };
25
- }
26
-
27
- editedTrans.date = transaction.valueDate;
28
-
29
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
30
- },
31
-
32
- calculateStartingBalance(sortedTransactions = [], balances = []) {
33
- return sortedTransactions.reduce(
34
- (total, trans) => {
35
- return total - amountToInteger(trans.transactionAmount.amount);
36
- },
37
- amountToInteger(balances[0]?.balanceAmount?.amount || 0),
38
- );
39
- },
40
- };
@@ -1,46 +0,0 @@
1
- import { formatPayeeName } from '../../util/payee-name.js';
2
-
3
- import Fallback from './integration-bank.js';
4
-
5
- /** @type {import('./bank.interface.js').IBank} */
6
- export default {
7
- ...Fallback,
8
-
9
- institutionIds: ['FORTUNEO_FTNOFRP1XXX'],
10
-
11
- normalizeTransaction(transaction, booked) {
12
- const editedTrans = { ...transaction };
13
-
14
- // Most of the information from the transaction is in the remittanceInformationUnstructuredArray field.
15
- // We extract the creditor and debtor names from this field.
16
- // The remittanceInformationUnstructuredArray field usually contain keywords like "Vir" for
17
- // bank transfers or "Carte 03/06" for card payments, as well as the date.
18
- // We remove these keywords to get a cleaner payee name.
19
- const keywordsToRemove = [
20
- 'VIR INST',
21
- 'VIR',
22
- 'PRLV',
23
- 'ANN CARTE',
24
- 'CARTE \\d{2}\\/\\d{2}',
25
- ];
26
-
27
- const details =
28
- transaction.remittanceInformationUnstructuredArray.join(' ');
29
- const amount = transaction.transactionAmount.amount;
30
-
31
- const regex = new RegExp(keywordsToRemove.join('|'), 'g');
32
- const payeeName = details.replace(regex, '').trim();
33
-
34
- // The amount is negative for outgoing transactions, positive for incoming transactions.
35
- const isCreditorPayee = parseFloat(amount) < 0;
36
-
37
- // The payee name is the creditor name for outgoing transactions and the debtor name for incoming transactions.
38
- const creditorName = isCreditorPayee ? payeeName : null;
39
- const debtorName = isCreditorPayee ? null : payeeName;
40
-
41
- editedTrans.creditorName = creditorName;
42
- editedTrans.debtorName = debtorName;
43
-
44
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
45
- },
46
- };
@@ -1,74 +0,0 @@
1
- import Fallback from './integration-bank.js';
2
-
3
- /** @type {import('./bank.interface.js').IBank} */
4
- export default {
5
- ...Fallback,
6
-
7
- institutionIds: ['HYPE_HYEEIT22'],
8
-
9
- normalizeTransaction(transaction, booked) {
10
- const editedTrans = { ...transaction };
11
-
12
- /** Online card payments - identified by "crd" transaction code
13
- * always start with PAGAMENTO PRESSO + <payee name>
14
- */
15
- if (transaction.proprietaryBankTransactionCode === 'crd') {
16
- // remove PAGAMENTO PRESSO and set payee name
17
- editedTrans.debtorName =
18
- transaction.remittanceInformationUnstructured?.slice(
19
- 'PAGAMENTO PRESSO '.length,
20
- );
21
- }
22
- /**
23
- * In-app money transfers (p2p) and bank transfers (bon) have remittance info structure like
24
- * DENARO (INVIATO/RICEVUTO) (A/DA) {payee_name} - {payment_info} (p2p)
25
- * HAI (INVIATO/RICEVUTO) UN BONIFICO (A/DA) {payee_name} - {payment_info} (bon)
26
- */
27
- if (
28
- transaction.proprietaryBankTransactionCode === 'p2p' ||
29
- transaction.proprietaryBankTransactionCode === 'bon'
30
- ) {
31
- // keep only {payment_info} portion of remittance info
32
- // NOTE: if {payee_name} contains dashes (unlikely / impossible?), this probably gets bugged!
33
- const infoIdx =
34
- transaction.remittanceInformationUnstructured.indexOf(' - ') + 3;
35
- editedTrans.remittanceInformationUnstructured =
36
- infoIdx === -1
37
- ? transaction.remittanceInformationUnstructured
38
- : transaction.remittanceInformationUnstructured.slice(infoIdx).trim();
39
- }
40
- /**
41
- * CONVERT ESCAPED UNICODE TO CODEPOINTS
42
- * p2p payments allow user to write arbitrary unicode strings as messages
43
- * gocardless reports unicode codepoints as \Uxxxx
44
- * so it groups them in 4bytes bundles
45
- * the code below assumes this is always the case
46
- */
47
- if (transaction.proprietaryBankTransactionCode === 'p2p') {
48
- let str = transaction.remittanceInformationUnstructured;
49
- let idx = str.indexOf('\\U');
50
- let start_idx = idx;
51
- let codepoints = [];
52
- while (idx !== -1) {
53
- codepoints.push(parseInt(str.slice(idx + 2, idx + 6), 16));
54
- const next_idx = str.indexOf('\\U', idx + 6);
55
- if (next_idx === idx + 6) {
56
- idx = next_idx;
57
- continue;
58
- }
59
- str =
60
- str.slice(0, start_idx) +
61
- String.fromCodePoint(...codepoints) +
62
- str.slice(idx + 6);
63
- codepoints = [];
64
- idx = str.indexOf('\\U'); // slight inefficiency?
65
- start_idx = idx;
66
- }
67
- editedTrans.remittanceInformationUnstructured = str;
68
- }
69
-
70
- editedTrans.date = transaction.valueDate || transaction.bookingDate;
71
-
72
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
73
- },
74
- };
@@ -1,70 +0,0 @@
1
- import Fallback from './integration-bank.js';
2
-
3
- /** @type {import('./bank.interface.js').IBank} */
4
- export default {
5
- ...Fallback,
6
-
7
- institutionIds: ['ING_INGBROBU'],
8
-
9
- normalizeTransaction(transaction, booked) {
10
- const editedTrans = { ...transaction };
11
-
12
- //Merchant transactions all have the same transactionId of 'NOTPROVIDED'.
13
- //For booked transactions, this can be set to the internalTransactionId
14
- //For pending transactions, this needs to be removed for them to show up in Actual
15
-
16
- //For deduplication to work better, payeeName needs to be standardized
17
- //and converted from a pending transaction form ("payeeName":"Card no: xxxxxxxxxxxx1111"') to a booked transaction form ("payeeName":"Card no: Xxxx Xxxx Xxxx 1111")
18
- if (transaction.transactionId === 'NOTPROVIDED') {
19
- //Some corner case transactions only have the `proprietaryBankTransactionCode` field, this need to be copied to `remittanceInformationUnstructured`
20
- if (
21
- transaction.proprietaryBankTransactionCode &&
22
- !transaction.remittanceInformationUnstructured
23
- ) {
24
- editedTrans.remittanceInformationUnstructured =
25
- transaction.proprietaryBankTransactionCode;
26
- }
27
-
28
- if (booked) {
29
- transaction.transactionId = transaction.internalTransactionId;
30
- if (
31
- transaction.remittanceInformationUnstructured &&
32
- transaction.remittanceInformationUnstructured
33
- .toLowerCase()
34
- .includes('card no:')
35
- ) {
36
- editedTrans.creditorName =
37
- transaction.remittanceInformationUnstructured.split(',')[0];
38
- //Catch all case for other types of payees
39
- } else {
40
- editedTrans.creditorName =
41
- transaction.remittanceInformationUnstructured;
42
- }
43
- } else {
44
- transaction.transactionId = null;
45
-
46
- if (
47
- transaction.remittanceInformationUnstructured &&
48
- transaction.remittanceInformationUnstructured
49
- .toLowerCase()
50
- .includes('card no:')
51
- ) {
52
- editedTrans.creditorName =
53
- transaction.remittanceInformationUnstructured.replace(
54
- /x{4}/g,
55
- 'Xxxx ',
56
- );
57
- //Catch all case for other types of payees
58
- } else {
59
- editedTrans.creditorName =
60
- transaction.remittanceInformationUnstructured;
61
- }
62
- //Remove remittanceInformationUnstructured from pending transactions, so the `notes` field remains empty (there is no merchant information)
63
- //Once booked, the right `notes` (containing the merchant) will be populated
64
- editedTrans.remittanceInformationUnstructured = null;
65
- }
66
- }
67
-
68
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
69
- },
70
- };
@@ -1,47 +0,0 @@
1
- import { amountToInteger } from '../utils.js';
2
-
3
- import Fallback from './integration-bank.js';
4
-
5
- /** @type {import('./bank.interface.js').IBank} */
6
- export default {
7
- ...Fallback,
8
-
9
- institutionIds: ['ING_INGDDEFF'],
10
-
11
- normalizeTransaction(transaction, booked) {
12
- const editedTrans = { ...transaction };
13
-
14
- const remittanceInformationMatch = /remittanceinformation:(.*)$/.exec(
15
- transaction.remittanceInformationUnstructured,
16
- );
17
-
18
- editedTrans.remittanceInformationUnstructured = remittanceInformationMatch
19
- ? remittanceInformationMatch[1]
20
- : transaction.remittanceInformationUnstructured;
21
-
22
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
23
- },
24
-
25
- sortTransactions(transactions = []) {
26
- return transactions.sort((a, b) => {
27
- const diff =
28
- +new Date(b.valueDate || b.bookingDate) -
29
- +new Date(a.valueDate || a.bookingDate);
30
- if (diff) return diff;
31
- const idA = parseInt(a.transactionId);
32
- const idB = parseInt(b.transactionId);
33
- if (!isNaN(idA) && !isNaN(idB)) return idB - idA;
34
- return 0;
35
- });
36
- },
37
-
38
- calculateStartingBalance(sortedTransactions = [], balances = []) {
39
- const currentBalance = balances.find(
40
- balance => 'interimBooked' === balance.balanceType,
41
- );
42
-
43
- return sortedTransactions.reduce((total, trans) => {
44
- return total - amountToInteger(trans.transactionAmount.amount);
45
- }, amountToInteger(currentBalance.balanceAmount.amount));
46
- },
47
- };
@@ -1,46 +0,0 @@
1
- import { amountToInteger } from '../utils.js';
2
-
3
- import Fallback from './integration-bank.js';
4
-
5
- /** @type {import('./bank.interface.js').IBank} */
6
- export default {
7
- ...Fallback,
8
-
9
- institutionIds: ['ING_PL_INGBPLPW'],
10
-
11
- normalizeTransaction(transaction, booked) {
12
- const editedTrans = { ...transaction };
13
-
14
- editedTrans.date = transaction.valueDate;
15
-
16
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
17
- },
18
-
19
- sortTransactions(transactions = []) {
20
- return transactions.sort((a, b) => {
21
- return (
22
- Number(b.transactionId.substr(2)) - Number(a.transactionId.substr(2))
23
- );
24
- });
25
- },
26
-
27
- calculateStartingBalance(sortedTransactions = [], balances = []) {
28
- if (sortedTransactions.length) {
29
- const oldestTransaction =
30
- sortedTransactions[sortedTransactions.length - 1];
31
- const oldestKnownBalance = amountToInteger(
32
- oldestTransaction.balanceAfterTransaction.balanceAmount.amount,
33
- );
34
- const oldestTransactionAmount = amountToInteger(
35
- oldestTransaction.transactionAmount.amount,
36
- );
37
-
38
- return oldestKnownBalance - oldestTransactionAmount;
39
- } else {
40
- return amountToInteger(
41
- balances.find(balance => 'interimBooked' === balance.balanceType)
42
- .balanceAmount.amount,
43
- );
44
- }
45
- },
46
- };
@@ -1,115 +0,0 @@
1
- import * as d from 'date-fns';
2
-
3
- import { formatPayeeName } from '../../util/payee-name.js';
4
- import {
5
- amountToInteger,
6
- printIban,
7
- sortByBookingDateOrValueDate,
8
- } from '../utils.js';
9
-
10
- const SORTED_BALANCE_TYPE_LIST = [
11
- 'closingBooked',
12
- 'expected',
13
- 'forwardAvailable',
14
- 'interimAvailable',
15
- 'interimBooked',
16
- 'nonInvoiced',
17
- 'openingBooked',
18
- ];
19
-
20
- /** @type {import('./bank.interface.js').IBank} */
21
- export default {
22
- institutionIds: ['IntegrationBank'],
23
-
24
- normalizeAccount(account) {
25
- console.debug(
26
- 'Available account properties for new institution integration',
27
- { account: JSON.stringify(account) },
28
- );
29
-
30
- return {
31
- account_id: account.id,
32
- institution: account.institution,
33
- mask: (account?.iban || '0000').slice(-4),
34
- iban: account?.iban || null,
35
- name: [
36
- account.name ?? account.displayName ?? account.product,
37
- printIban(account),
38
- account.currency,
39
- ]
40
- .filter(Boolean)
41
- .join(' '),
42
- official_name: account.product ?? `integration-${account.institution_id}`,
43
- type: 'checking',
44
- };
45
- },
46
-
47
- normalizeTransaction(transaction, _booked, editedTransaction = null) {
48
- const trans = editedTransaction ?? transaction;
49
-
50
- const date =
51
- trans.date ||
52
- transaction.bookingDate ||
53
- transaction.bookingDateTime ||
54
- transaction.valueDate ||
55
- transaction.valueDateTime;
56
-
57
- // If we couldn't find a valid date field we filter out this transaction
58
- // and hope that we will import it again once the bank has processed the
59
- // transaction further.
60
- if (!date) {
61
- return null;
62
- }
63
-
64
- const notes =
65
- trans.notes ??
66
- trans.remittanceInformationUnstructured ??
67
- trans.remittanceInformationUnstructuredArray?.join(' ');
68
-
69
- transaction.remittanceInformationUnstructuredArrayString =
70
- transaction.remittanceInformationUnstructuredArray?.join(',');
71
- transaction.remittanceInformationStructuredArrayString =
72
- transaction.remittanceInformationStructuredArray?.join(',');
73
-
74
- return {
75
- ...transaction,
76
- payeeName: trans.payeeName ?? formatPayeeName(trans),
77
- date: d.format(d.parseISO(date), 'yyyy-MM-dd'),
78
- notes,
79
- };
80
- },
81
-
82
- sortTransactions(transactions = []) {
83
- console.debug(
84
- 'Available (first 10) transactions properties for new integration of institution in sortTransactions function',
85
- { top10Transactions: JSON.stringify(transactions.slice(0, 10)) },
86
- );
87
- return sortByBookingDateOrValueDate(transactions);
88
- },
89
-
90
- calculateStartingBalance(sortedTransactions = [], balances = []) {
91
- console.debug(
92
- 'Available (first 10) transactions properties for new integration of institution in calculateStartingBalance function',
93
- {
94
- balances: JSON.stringify(balances),
95
- top10SortedTransactions: JSON.stringify(
96
- sortedTransactions.slice(0, 10),
97
- ),
98
- },
99
- );
100
-
101
- const currentBalance = balances
102
- .filter(item => SORTED_BALANCE_TYPE_LIST.includes(item.balanceType))
103
- .sort(
104
- (a, b) =>
105
- SORTED_BALANCE_TYPE_LIST.indexOf(a.balanceType) -
106
- SORTED_BALANCE_TYPE_LIST.indexOf(b.balanceType),
107
- )[0];
108
- return sortedTransactions.reduce(
109
- (total, trans) => {
110
- return total - amountToInteger(trans.transactionAmount.amount);
111
- },
112
- amountToInteger(currentBalance?.balanceAmount?.amount || 0),
113
- );
114
- },
115
- };
@@ -1,18 +0,0 @@
1
- import Fallback from './integration-bank.js';
2
-
3
- /** @type {import('./bank.interface.js').IBank} */
4
- export default {
5
- ...Fallback,
6
-
7
- institutionIds: ['ISYBANK_ITBBITMM'],
8
-
9
- // It has been reported that valueDate is more accurate than booking date
10
- // when it is provided
11
- normalizeTransaction(transaction, booked) {
12
- const editedTrans = { ...transaction };
13
-
14
- editedTrans.date = transaction.valueDate ?? transaction.bookingDate;
15
-
16
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
17
- },
18
- };
@@ -1,33 +0,0 @@
1
- import Fallback from './integration-bank.js';
2
- import { extractPayeeNameFromRemittanceInfo } from './util/extract-payeeName-from-remittanceInfo.js';
3
-
4
- /** @type {import('./bank.interface.js').IBank} */
5
- export default {
6
- ...Fallback,
7
-
8
- institutionIds: ['KBC_KREDBEBB'],
9
-
10
- /**
11
- * For negative amounts, the only payee information we have is returned in
12
- * remittanceInformationUnstructured.
13
- */
14
- normalizeTransaction(transaction, booked) {
15
- const editedTrans = { ...transaction };
16
-
17
- if (Number(transaction.transactionAmount.amount) > 0) {
18
- editedTrans.payeeName =
19
- transaction.debtorName ||
20
- transaction.remittanceInformationUnstructured ||
21
- 'undefined';
22
- } else {
23
- editedTrans.payeeName =
24
- transaction.creditorName ||
25
- extractPayeeNameFromRemittanceInfo(
26
- transaction.remittanceInformationUnstructured,
27
- ['Betaling met', 'Domiciliëring', 'Overschrijving'],
28
- );
29
- }
30
-
31
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
32
- },
33
- };
@@ -1,36 +0,0 @@
1
- import d from 'date-fns';
2
-
3
- import Fallback from './integration-bank.js';
4
-
5
- /** @type {import('./bank.interface.js').IBank} */
6
- export default {
7
- ...Fallback,
8
-
9
- institutionIds: ['LHV_LHVBEE22'],
10
-
11
- normalizeTransaction(transaction, booked) {
12
- const editedTrans = { ...transaction };
13
-
14
- // extract bookingDate and creditorName for card transactions, e.g.
15
- // (..1234) 2025-01-02 09:32 CrustumOU\Poordi 3\Tallinn\10156 ESTEST
16
- // bookingDate: 2025-01-02
17
- // creditorName: CrustumOU
18
- const cardTxRegex =
19
- /^\(\.\.(\d{4})\) (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}) (.+)$/g;
20
- const cardTxMatch = cardTxRegex.exec(
21
- transaction?.remittanceInformationUnstructured,
22
- );
23
-
24
- if (cardTxMatch) {
25
- const extractedDate = d.parse(cardTxMatch[2], 'yyyy-MM-dd', new Date());
26
-
27
- editedTrans.payeeName = cardTxMatch[4].split('\\')[0].trim();
28
-
29
- if (booked && d.isValid(extractedDate)) {
30
- editedTrans.date = d.format(extractedDate, 'yyyy-MM-dd');
31
- }
32
- }
33
-
34
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
35
- },
36
- };
@@ -1,56 +0,0 @@
1
- import { amountToInteger } from '../utils.js';
2
-
3
- import Fallback from './integration-bank.js';
4
-
5
- /** @type {import('./bank.interface.js').IBank} */
6
- export default {
7
- ...Fallback,
8
-
9
- institutionIds: ['MBANK_RETAIL_BREXPLPW'],
10
-
11
- /**
12
- * When requesting transaction details for MBANK_RETAIL_BREXPLPW
13
- * using gocardless API, it seems that bookingDate and valueDate are swapped.
14
- * valueDate will always come before bookingDate, so as a simple fix,
15
- * I have overwritten integration-bank.normalizeTransaction() here,
16
- * swapped dates back (by giving valueDate higher priority) and
17
- * called parent method with edited transaction as argument
18
- */
19
- normalizeTransaction(transaction, booked) {
20
- const editedTrans = { ...transaction };
21
-
22
- const date =
23
- transaction.valueDate ||
24
- transaction.valueDateTime ||
25
- transaction.bookingDate ||
26
- transaction.bookingDateTime;
27
-
28
- editedTrans.date = date;
29
-
30
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
31
- },
32
-
33
- sortTransactions(transactions = []) {
34
- return transactions.sort(
35
- (a, b) => Number(b.transactionId) - Number(a.transactionId),
36
- );
37
- },
38
-
39
- /**
40
- * For MBANK_RETAIL_BREXPLPW we don't know what balance was
41
- * after each transaction so we have to calculate it by getting
42
- * current balance from the account and subtract all the transactions
43
- *
44
- * As a current balance we use `interimBooked` balance type because
45
- * it includes transaction placed during current day
46
- */
47
- calculateStartingBalance(sortedTransactions = [], balances = []) {
48
- const currentBalance = balances.find(
49
- balance => 'interimBooked' === balance.balanceType,
50
- );
51
-
52
- return sortedTransactions.reduce((total, trans) => {
53
- return total - amountToInteger(trans.transactionAmount.amount);
54
- }, amountToInteger(currentBalance.balanceAmount.amount));
55
- },
56
- };
@@ -1,46 +0,0 @@
1
- import Fallback from './integration-bank.js';
2
-
3
- /** @type {import('./bank.interface.js').IBank} */
4
- export default {
5
- ...Fallback,
6
-
7
- institutionIds: ['NATIONWIDE_NAIAGB21'],
8
-
9
- normalizeTransaction(transaction, booked) {
10
- const editedTrans = { ...transaction };
11
-
12
- // Nationwide can sometimes return pending transactions with a date
13
- // representing the latest a transaction could be booked. This stops
14
- // actual's deduplication logic from working as it only checks 7 days
15
- // ahead/behind and the transactionID from Nationwide changes when a
16
- // transaction is booked
17
- if (!booked) {
18
- const useDate = new Date(
19
- Math.min(
20
- new Date(transaction.bookingDate).getTime(),
21
- new Date().getTime(),
22
- ),
23
- );
24
- editedTrans.date = useDate.toISOString().slice(0, 10);
25
- }
26
-
27
- // Nationwide also occasionally returns erroneous transaction_ids
28
- // that are malformed and can even change after import. This will ignore
29
- // these ids and unset them. When a correct ID is returned then it will
30
- // update via the deduplication logic
31
- const debitCreditRegex = /^00(DEB|CRED)IT.+$/;
32
- const validLengths = [
33
- 40, // Nationwide credit cards
34
- 32, // Nationwide current accounts
35
- ];
36
-
37
- if (
38
- transaction.transactionId?.match(debitCreditRegex) ||
39
- !validLengths.includes(transaction.transactionId?.length)
40
- ) {
41
- transaction.transactionId = null;
42
- }
43
-
44
- return Fallback.normalizeTransaction(transaction, booked, editedTrans);
45
- },
46
- };