@tasenor/common-node 1.9.16

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 (326) hide show
  1. package/.eslintrc.js +4 -0
  2. package/LICENSE +21 -0
  3. package/dist/tasenor-common-node/src/cli.d.ts +81 -0
  4. package/dist/tasenor-common-node/src/cli.js +242 -0
  5. package/dist/tasenor-common-node/src/cli.js.map +1 -0
  6. package/dist/tasenor-common-node/src/commands/account.d.ts +12 -0
  7. package/dist/tasenor-common-node/src/commands/account.js +58 -0
  8. package/dist/tasenor-common-node/src/commands/account.js.map +1 -0
  9. package/dist/tasenor-common-node/src/commands/balance.d.ts +11 -0
  10. package/dist/tasenor-common-node/src/commands/balance.js +117 -0
  11. package/dist/tasenor-common-node/src/commands/balance.js.map +1 -0
  12. package/dist/tasenor-common-node/src/commands/db.d.ts +14 -0
  13. package/dist/tasenor-common-node/src/commands/db.js +69 -0
  14. package/dist/tasenor-common-node/src/commands/db.js.map +1 -0
  15. package/dist/tasenor-common-node/src/commands/entry.d.ts +13 -0
  16. package/dist/tasenor-common-node/src/commands/entry.js +106 -0
  17. package/dist/tasenor-common-node/src/commands/entry.js.map +1 -0
  18. package/dist/tasenor-common-node/src/commands/import.d.ts +17 -0
  19. package/dist/tasenor-common-node/src/commands/import.js +140 -0
  20. package/dist/tasenor-common-node/src/commands/import.js.map +1 -0
  21. package/dist/tasenor-common-node/src/commands/importer.d.ts +13 -0
  22. package/dist/tasenor-common-node/src/commands/importer.js +71 -0
  23. package/dist/tasenor-common-node/src/commands/importer.js.map +1 -0
  24. package/dist/tasenor-common-node/src/commands/index.d.ts +191 -0
  25. package/dist/tasenor-common-node/src/commands/index.js +482 -0
  26. package/dist/tasenor-common-node/src/commands/index.js.map +1 -0
  27. package/dist/tasenor-common-node/src/commands/period.d.ts +12 -0
  28. package/dist/tasenor-common-node/src/commands/period.js +48 -0
  29. package/dist/tasenor-common-node/src/commands/period.js.map +1 -0
  30. package/dist/tasenor-common-node/src/commands/plugin.d.ts +15 -0
  31. package/dist/tasenor-common-node/src/commands/plugin.js +78 -0
  32. package/dist/tasenor-common-node/src/commands/plugin.js.map +1 -0
  33. package/dist/tasenor-common-node/src/commands/report.d.ts +11 -0
  34. package/dist/tasenor-common-node/src/commands/report.js +96 -0
  35. package/dist/tasenor-common-node/src/commands/report.js.map +1 -0
  36. package/dist/tasenor-common-node/src/commands/settings.d.ts +10 -0
  37. package/dist/tasenor-common-node/src/commands/settings.js +64 -0
  38. package/dist/tasenor-common-node/src/commands/settings.js.map +1 -0
  39. package/dist/tasenor-common-node/src/commands/stock.d.ts +8 -0
  40. package/dist/tasenor-common-node/src/commands/stock.js +73 -0
  41. package/dist/tasenor-common-node/src/commands/stock.js.map +1 -0
  42. package/dist/tasenor-common-node/src/commands/tag.d.ts +13 -0
  43. package/dist/tasenor-common-node/src/commands/tag.js +89 -0
  44. package/dist/tasenor-common-node/src/commands/tag.js.map +1 -0
  45. package/dist/tasenor-common-node/src/commands/tx.d.ts +12 -0
  46. package/dist/tasenor-common-node/src/commands/tx.js +81 -0
  47. package/dist/tasenor-common-node/src/commands/tx.js.map +1 -0
  48. package/dist/tasenor-common-node/src/commands/user.d.ts +12 -0
  49. package/dist/tasenor-common-node/src/commands/user.js +52 -0
  50. package/dist/tasenor-common-node/src/commands/user.js.map +1 -0
  51. package/dist/tasenor-common-node/src/database/BookkeeperImporter.d.ts +77 -0
  52. package/dist/tasenor-common-node/src/database/BookkeeperImporter.js +343 -0
  53. package/dist/tasenor-common-node/src/database/BookkeeperImporter.js.map +1 -0
  54. package/dist/tasenor-common-node/src/database/DB.d.ts +51 -0
  55. package/dist/tasenor-common-node/src/database/DB.js +354 -0
  56. package/dist/tasenor-common-node/src/database/DB.js.map +1 -0
  57. package/dist/tasenor-common-node/src/database/index.d.ts +7 -0
  58. package/dist/tasenor-common-node/src/database/index.js +8 -0
  59. package/dist/tasenor-common-node/src/database/index.js.map +1 -0
  60. package/dist/tasenor-common-node/src/doccer.d.ts +29 -0
  61. package/dist/tasenor-common-node/src/doccer.js +30 -0
  62. package/dist/tasenor-common-node/src/doccer.js.map +1 -0
  63. package/dist/tasenor-common-node/src/error.d.ts +30 -0
  64. package/dist/tasenor-common-node/src/error.js +35 -0
  65. package/dist/tasenor-common-node/src/error.js.map +1 -0
  66. package/dist/tasenor-common-node/src/export/Exporter.d.ts +69 -0
  67. package/dist/tasenor-common-node/src/export/Exporter.js +123 -0
  68. package/dist/tasenor-common-node/src/export/Exporter.js.map +1 -0
  69. package/dist/tasenor-common-node/src/export/TasenorExporter.d.ts +55 -0
  70. package/dist/tasenor-common-node/src/export/TasenorExporter.js +135 -0
  71. package/dist/tasenor-common-node/src/export/TasenorExporter.js.map +1 -0
  72. package/dist/tasenor-common-node/src/export/TilitinExporter.d.ts +71 -0
  73. package/dist/tasenor-common-node/src/export/TilitinExporter.js +290 -0
  74. package/dist/tasenor-common-node/src/export/TilitinExporter.js.map +1 -0
  75. package/dist/tasenor-common-node/src/export/index.d.ts +8 -0
  76. package/dist/tasenor-common-node/src/export/index.js +9 -0
  77. package/dist/tasenor-common-node/src/export/index.js.map +1 -0
  78. package/dist/tasenor-common-node/src/import/TextFileProcessHandler.d.ts +104 -0
  79. package/dist/tasenor-common-node/src/import/TextFileProcessHandler.js +354 -0
  80. package/dist/tasenor-common-node/src/import/TextFileProcessHandler.js.map +1 -0
  81. package/dist/tasenor-common-node/src/import/TransactionImportConnector.d.ts +38 -0
  82. package/dist/tasenor-common-node/src/import/TransactionImportConnector.js +27 -0
  83. package/dist/tasenor-common-node/src/import/TransactionImportConnector.js.map +1 -0
  84. package/dist/tasenor-common-node/src/import/TransactionImportHandler.d.ts +173 -0
  85. package/dist/tasenor-common-node/src/import/TransactionImportHandler.js +733 -0
  86. package/dist/tasenor-common-node/src/import/TransactionImportHandler.js.map +1 -0
  87. package/dist/tasenor-common-node/src/import/TransactionRules.d.ts +238 -0
  88. package/dist/tasenor-common-node/src/import/TransactionRules.js +522 -0
  89. package/dist/tasenor-common-node/src/import/TransactionRules.js.map +1 -0
  90. package/dist/tasenor-common-node/src/import/TransactionUI.d.ts +181 -0
  91. package/dist/tasenor-common-node/src/import/TransactionUI.js +482 -0
  92. package/dist/tasenor-common-node/src/import/TransactionUI.js.map +1 -0
  93. package/dist/tasenor-common-node/src/import/TransferAnalyzer.d.ts +324 -0
  94. package/dist/tasenor-common-node/src/import/TransferAnalyzer.js +1379 -0
  95. package/dist/tasenor-common-node/src/import/TransferAnalyzer.js.map +1 -0
  96. package/dist/tasenor-common-node/src/import/index.d.ts +11 -0
  97. package/dist/tasenor-common-node/src/import/index.js +12 -0
  98. package/dist/tasenor-common-node/src/import/index.js.map +1 -0
  99. package/dist/tasenor-common-node/src/index.d.ts +12 -0
  100. package/dist/tasenor-common-node/src/index.js +13 -0
  101. package/dist/tasenor-common-node/src/index.js.map +1 -0
  102. package/dist/tasenor-common-node/src/net/crypto.d.ts +33 -0
  103. package/dist/tasenor-common-node/src/net/crypto.js +63 -0
  104. package/dist/tasenor-common-node/src/net/crypto.js.map +1 -0
  105. package/dist/tasenor-common-node/src/net/git.d.ts +49 -0
  106. package/dist/tasenor-common-node/src/net/git.js +137 -0
  107. package/dist/tasenor-common-node/src/net/git.js.map +1 -0
  108. package/dist/tasenor-common-node/src/net/index.d.ts +10 -0
  109. package/dist/tasenor-common-node/src/net/index.js +11 -0
  110. package/dist/tasenor-common-node/src/net/index.js.map +1 -0
  111. package/dist/tasenor-common-node/src/net/middleware.d.ts +61 -0
  112. package/dist/tasenor-common-node/src/net/middleware.js +220 -0
  113. package/dist/tasenor-common-node/src/net/middleware.js.map +1 -0
  114. package/dist/tasenor-common-node/src/net/tokens.d.ts +50 -0
  115. package/dist/tasenor-common-node/src/net/tokens.js +141 -0
  116. package/dist/tasenor-common-node/src/net/tokens.js.map +1 -0
  117. package/dist/tasenor-common-node/src/net/vault.d.ts +67 -0
  118. package/dist/tasenor-common-node/src/net/vault.js +145 -0
  119. package/dist/tasenor-common-node/src/net/vault.js.map +1 -0
  120. package/dist/tasenor-common-node/src/plugins/BackendPlugin.d.ts +91 -0
  121. package/dist/tasenor-common-node/src/plugins/BackendPlugin.js +165 -0
  122. package/dist/tasenor-common-node/src/plugins/BackendPlugin.js.map +1 -0
  123. package/dist/tasenor-common-node/src/plugins/DataPlugin.d.ts +13 -0
  124. package/dist/tasenor-common-node/src/plugins/DataPlugin.js +26 -0
  125. package/dist/tasenor-common-node/src/plugins/DataPlugin.js.map +1 -0
  126. package/dist/tasenor-common-node/src/plugins/ImportPlugin.d.ts +188 -0
  127. package/dist/tasenor-common-node/src/plugins/ImportPlugin.js +204 -0
  128. package/dist/tasenor-common-node/src/plugins/ImportPlugin.js.map +1 -0
  129. package/dist/tasenor-common-node/src/plugins/ReportPlugin.d.ts +132 -0
  130. package/dist/tasenor-common-node/src/plugins/ReportPlugin.js +393 -0
  131. package/dist/tasenor-common-node/src/plugins/ReportPlugin.js.map +1 -0
  132. package/dist/tasenor-common-node/src/plugins/SchemePlugin.d.ts +34 -0
  133. package/dist/tasenor-common-node/src/plugins/SchemePlugin.js +47 -0
  134. package/dist/tasenor-common-node/src/plugins/SchemePlugin.js.map +1 -0
  135. package/dist/tasenor-common-node/src/plugins/ServicePlugin.d.ts +80 -0
  136. package/dist/tasenor-common-node/src/plugins/ServicePlugin.js +168 -0
  137. package/dist/tasenor-common-node/src/plugins/ServicePlugin.js.map +1 -0
  138. package/dist/tasenor-common-node/src/plugins/ToolPlugin.d.ts +27 -0
  139. package/dist/tasenor-common-node/src/plugins/ToolPlugin.js +37 -0
  140. package/dist/tasenor-common-node/src/plugins/ToolPlugin.js.map +1 -0
  141. package/dist/tasenor-common-node/src/plugins/index.d.ts +13 -0
  142. package/dist/tasenor-common-node/src/plugins/index.js +14 -0
  143. package/dist/tasenor-common-node/src/plugins/index.js.map +1 -0
  144. package/dist/tasenor-common-node/src/plugins/plugins.d.ts +101 -0
  145. package/dist/tasenor-common-node/src/plugins/plugins.js +292 -0
  146. package/dist/tasenor-common-node/src/plugins/plugins.js.map +1 -0
  147. package/dist/tasenor-common-node/src/process/Process.d.ts +108 -0
  148. package/dist/tasenor-common-node/src/process/Process.js +335 -0
  149. package/dist/tasenor-common-node/src/process/Process.js.map +1 -0
  150. package/dist/tasenor-common-node/src/process/ProcessConnector.d.ts +24 -0
  151. package/dist/tasenor-common-node/src/process/ProcessConnector.js +28 -0
  152. package/dist/tasenor-common-node/src/process/ProcessConnector.js.map +1 -0
  153. package/dist/tasenor-common-node/src/process/ProcessFile.d.ts +69 -0
  154. package/dist/tasenor-common-node/src/process/ProcessFile.js +145 -0
  155. package/dist/tasenor-common-node/src/process/ProcessFile.js.map +1 -0
  156. package/dist/tasenor-common-node/src/process/ProcessHandler.d.ts +60 -0
  157. package/dist/tasenor-common-node/src/process/ProcessHandler.js +73 -0
  158. package/dist/tasenor-common-node/src/process/ProcessHandler.js.map +1 -0
  159. package/dist/tasenor-common-node/src/process/ProcessStep.d.ts +52 -0
  160. package/dist/tasenor-common-node/src/process/ProcessStep.js +78 -0
  161. package/dist/tasenor-common-node/src/process/ProcessStep.js.map +1 -0
  162. package/dist/tasenor-common-node/src/process/ProcessingSystem.d.ts +60 -0
  163. package/dist/tasenor-common-node/src/process/ProcessingSystem.js +182 -0
  164. package/dist/tasenor-common-node/src/process/ProcessingSystem.js.map +1 -0
  165. package/dist/tasenor-common-node/src/process/index.d.ts +11 -0
  166. package/dist/tasenor-common-node/src/process/index.js +12 -0
  167. package/dist/tasenor-common-node/src/process/index.js.map +1 -0
  168. package/dist/tasenor-common-node/src/reports/conversions.d.ts +8 -0
  169. package/dist/tasenor-common-node/src/reports/conversions.js +47 -0
  170. package/dist/tasenor-common-node/src/reports/conversions.js.map +1 -0
  171. package/dist/tasenor-common-node/src/reports/index.d.ts +6 -0
  172. package/dist/tasenor-common-node/src/reports/index.js +7 -0
  173. package/dist/tasenor-common-node/src/reports/index.js.map +1 -0
  174. package/dist/tasenor-common-node/src/server/ISPDemoServer.d.ts +43 -0
  175. package/dist/tasenor-common-node/src/server/ISPDemoServer.js +112 -0
  176. package/dist/tasenor-common-node/src/server/ISPDemoServer.js.map +1 -0
  177. package/dist/tasenor-common-node/src/server/api.d.ts +15 -0
  178. package/dist/tasenor-common-node/src/server/api.js +27 -0
  179. package/dist/tasenor-common-node/src/server/api.js.map +1 -0
  180. package/dist/tasenor-common-node/src/server/index.d.ts +7 -0
  181. package/dist/tasenor-common-node/src/server/index.js +8 -0
  182. package/dist/tasenor-common-node/src/server/index.js.map +1 -0
  183. package/dist/tasenor-common-node/src/server/router.d.ts +5 -0
  184. package/dist/tasenor-common-node/src/server/router.js +37 -0
  185. package/dist/tasenor-common-node/src/server/router.js.map +1 -0
  186. package/dist/tasenor-common-node/src/system.d.ts +27 -0
  187. package/dist/tasenor-common-node/src/system.js +95 -0
  188. package/dist/tasenor-common-node/src/system.js.map +1 -0
  189. package/dist/tasenor-common-node/src/testing/ProcessingSystemMock.d.ts +21 -0
  190. package/dist/tasenor-common-node/src/testing/ProcessingSystemMock.js +33 -0
  191. package/dist/tasenor-common-node/src/testing/ProcessingSystemMock.js.map +1 -0
  192. package/dist/tasenor-common-node/src/testing/UnitTestImportConnector.d.ts +24 -0
  193. package/dist/tasenor-common-node/src/testing/UnitTestImportConnector.js +68 -0
  194. package/dist/tasenor-common-node/src/testing/UnitTestImportConnector.js.map +1 -0
  195. package/dist/tasenor-common-node/src/testing/UnitTester.d.ts +64 -0
  196. package/dist/tasenor-common-node/src/testing/UnitTester.js +199 -0
  197. package/dist/tasenor-common-node/src/testing/UnitTester.js.map +1 -0
  198. package/dist/tasenor-common-node/src/testing/index.d.ts +4 -0
  199. package/dist/tasenor-common-node/src/testing/index.js +5 -0
  200. package/dist/tasenor-common-node/src/testing/index.js.map +1 -0
  201. package/dist/tasenor-common-node/src/testing/test-handlers.d.ts +13 -0
  202. package/dist/tasenor-common-node/src/testing/test-handlers.js +52 -0
  203. package/dist/tasenor-common-node/src/testing/test-handlers.js.map +1 -0
  204. package/dist/tasenor-common-node/tests/TransactionRules.spec.d.ts +1 -0
  205. package/dist/tasenor-common-node/tests/TransactionRules.spec.js +64 -0
  206. package/dist/tasenor-common-node/tests/TransactionRules.spec.js.map +1 -0
  207. package/dist/tasenor-common-node/tests/TransferAnalyzer-account-address.spec.d.ts +1 -0
  208. package/dist/tasenor-common-node/tests/TransferAnalyzer-account-address.spec.js +80 -0
  209. package/dist/tasenor-common-node/tests/TransferAnalyzer-account-address.spec.js.map +1 -0
  210. package/dist/tasenor-common-node/tests/TransferAnalyzer-buying-and-selling.spec.d.ts +1 -0
  211. package/dist/tasenor-common-node/tests/TransferAnalyzer-buying-and-selling.spec.js +342 -0
  212. package/dist/tasenor-common-node/tests/TransferAnalyzer-buying-and-selling.spec.js.map +1 -0
  213. package/dist/tasenor-common-node/tests/TransferAnalyzer-loans.spec.d.ts +1 -0
  214. package/dist/tasenor-common-node/tests/TransferAnalyzer-loans.spec.js +174 -0
  215. package/dist/tasenor-common-node/tests/TransferAnalyzer-loans.spec.js.map +1 -0
  216. package/dist/tasenor-common-node/tests/TransferAnalyzer-multiple-null-amounts.spec.d.ts +1 -0
  217. package/dist/tasenor-common-node/tests/TransferAnalyzer-multiple-null-amounts.spec.js +175 -0
  218. package/dist/tasenor-common-node/tests/TransferAnalyzer-multiple-null-amounts.spec.js.map +1 -0
  219. package/dist/tasenor-common-node/tests/password.spec.d.ts +1 -0
  220. package/dist/tasenor-common-node/tests/password.spec.js +8 -0
  221. package/dist/tasenor-common-node/tests/password.spec.js.map +1 -0
  222. package/dist/tasenor-common-node/tests/tokens.spec.d.ts +1 -0
  223. package/dist/tasenor-common-node/tests/tokens.spec.js +49 -0
  224. package/dist/tasenor-common-node/tests/tokens.spec.js.map +1 -0
  225. package/dist/tasenor-common-node/tests/vault.spec.d.ts +1 -0
  226. package/dist/tasenor-common-node/tests/vault.spec.js +19 -0
  227. package/dist/tasenor-common-node/tests/vault.spec.js.map +1 -0
  228. package/dist/tasenor-common-plugins/src/CoinbaseImport/backend/CoinbaseHandler.d.ts +11 -0
  229. package/dist/tasenor-common-plugins/src/CoinbaseImport/backend/CoinbaseHandler.js +30 -0
  230. package/dist/tasenor-common-plugins/src/CoinbaseImport/backend/CoinbaseHandler.js.map +1 -0
  231. package/dist/tasenor-common-plugins/src/IncomeAndExpenses/backend/index.d.ts +5 -0
  232. package/dist/tasenor-common-plugins/src/IncomeAndExpenses/backend/index.js +350 -0
  233. package/dist/tasenor-common-plugins/src/IncomeAndExpenses/backend/index.js.map +1 -0
  234. package/dist/tasenor-common-plugins/src/KrakenImport/backend/KrakenHandler.d.ts +23 -0
  235. package/dist/tasenor-common-plugins/src/KrakenImport/backend/KrakenHandler.js +83 -0
  236. package/dist/tasenor-common-plugins/src/KrakenImport/backend/KrakenHandler.js.map +1 -0
  237. package/dist/tasenor-common-plugins/src/LynxImport/backend/LynxHandler.d.ts +28 -0
  238. package/dist/tasenor-common-plugins/src/LynxImport/backend/LynxHandler.js +340 -0
  239. package/dist/tasenor-common-plugins/src/LynxImport/backend/LynxHandler.js.map +1 -0
  240. package/dist/tasenor-common-plugins/src/NordeaImport/backend/NordeaHandler.d.ts +11 -0
  241. package/dist/tasenor-common-plugins/src/NordeaImport/backend/NordeaHandler.js +39 -0
  242. package/dist/tasenor-common-plugins/src/NordeaImport/backend/NordeaHandler.js.map +1 -0
  243. package/dist/tasenor-common-plugins/src/NordnetImport/backend/NordnetHandler.d.ts +17 -0
  244. package/dist/tasenor-common-plugins/src/NordnetImport/backend/NordnetHandler.js +66 -0
  245. package/dist/tasenor-common-plugins/src/NordnetImport/backend/NordnetHandler.js.map +1 -0
  246. package/dist/tasenor-common-plugins/src/TITOImport/backend/TITOHandler.d.ts +13 -0
  247. package/dist/tasenor-common-plugins/src/TITOImport/backend/TITOHandler.js +241 -0
  248. package/dist/tasenor-common-plugins/src/TITOImport/backend/TITOHandler.js.map +1 -0
  249. package/jest.config.js +1 -0
  250. package/package.json +62 -0
  251. package/src/cli.ts +267 -0
  252. package/src/commands/account.ts +69 -0
  253. package/src/commands/balance.ts +131 -0
  254. package/src/commands/db.ts +84 -0
  255. package/src/commands/entry.ts +117 -0
  256. package/src/commands/import.ts +160 -0
  257. package/src/commands/importer.ts +84 -0
  258. package/src/commands/index.ts +534 -0
  259. package/src/commands/period.ts +59 -0
  260. package/src/commands/plugin.ts +95 -0
  261. package/src/commands/report.ts +113 -0
  262. package/src/commands/settings.ts +75 -0
  263. package/src/commands/stock.ts +80 -0
  264. package/src/commands/tag.ts +102 -0
  265. package/src/commands/tx.ts +93 -0
  266. package/src/commands/user.ts +65 -0
  267. package/src/database/BookkeeperImporter.ts +358 -0
  268. package/src/database/DB.ts +396 -0
  269. package/src/database/index.ts +7 -0
  270. package/src/doccer.ts +29 -0
  271. package/src/error.ts +32 -0
  272. package/src/export/Exporter.ts +136 -0
  273. package/src/export/TasenorExporter.ts +144 -0
  274. package/src/export/TilitinExporter.ts +302 -0
  275. package/src/export/index.ts +8 -0
  276. package/src/import/TextFileProcessHandler.ts +384 -0
  277. package/src/import/TransactionImportConnector.ts +65 -0
  278. package/src/import/TransactionImportHandler.ts +819 -0
  279. package/src/import/TransactionRules.ts +570 -0
  280. package/src/import/TransactionUI.ts +520 -0
  281. package/src/import/TransferAnalyzer.ts +1450 -0
  282. package/src/import/index.ts +11 -0
  283. package/src/index.ts +12 -0
  284. package/src/net/crypto.ts +69 -0
  285. package/src/net/git.ts +151 -0
  286. package/src/net/index.ts +10 -0
  287. package/src/net/middleware.ts +261 -0
  288. package/src/net/tokens.ts +140 -0
  289. package/src/net/vault.ts +161 -0
  290. package/src/plugins/BackendPlugin.ts +188 -0
  291. package/src/plugins/DataPlugin.ts +29 -0
  292. package/src/plugins/ImportPlugin.ts +211 -0
  293. package/src/plugins/ReportPlugin.ts +443 -0
  294. package/src/plugins/SchemePlugin.ts +56 -0
  295. package/src/plugins/ServicePlugin.ts +188 -0
  296. package/src/plugins/ToolPlugin.ts +44 -0
  297. package/src/plugins/index.ts +13 -0
  298. package/src/plugins/plugins.ts +345 -0
  299. package/src/process/Process.ts +368 -0
  300. package/src/process/ProcessConnector.ts +45 -0
  301. package/src/process/ProcessFile.ts +169 -0
  302. package/src/process/ProcessHandler.ts +94 -0
  303. package/src/process/ProcessStep.ts +100 -0
  304. package/src/process/ProcessingSystem.ts +202 -0
  305. package/src/process/index.ts +11 -0
  306. package/src/reports/conversions.ts +52 -0
  307. package/src/reports/index.ts +6 -0
  308. package/src/server/ISPDemoServer.ts +122 -0
  309. package/src/server/api.ts +37 -0
  310. package/src/server/index.ts +7 -0
  311. package/src/server/router.ts +60 -0
  312. package/src/system.ts +96 -0
  313. package/src/testing/ProcessingSystemMock.ts +45 -0
  314. package/src/testing/UnitTestImportConnector.ts +86 -0
  315. package/src/testing/UnitTester.ts +231 -0
  316. package/src/testing/index.ts +4 -0
  317. package/src/testing/test-handlers.ts +55 -0
  318. package/tests/TransactionRules.spec.ts +73 -0
  319. package/tests/TransferAnalyzer-account-address.spec.ts +87 -0
  320. package/tests/TransferAnalyzer-buying-and-selling.spec.ts +354 -0
  321. package/tests/TransferAnalyzer-loans.spec.ts +197 -0
  322. package/tests/TransferAnalyzer-multiple-null-amounts.spec.ts +181 -0
  323. package/tests/password.spec.ts +8 -0
  324. package/tests/tokens.spec.ts +52 -0
  325. package/tests/vault.spec.ts +20 -0
  326. package/tsconfig.json +13 -0
@@ -0,0 +1,522 @@
1
+ import { isAssetTransfer, RuleParsingError, RulesEngine, isUIQueryRef, warning, debug, error } from '@dataplug/tasenor-common';
2
+ import clone from 'clone';
3
+ import { BadState, SystemError } from '../error';
4
+ /**
5
+ * ## Transaction rule system
6
+ *
7
+ * The classification of the import data uses rule system describing how to transform segmented
8
+ * data to *transfers*, i.e. generic description of bookkeeping events. Initially in the beginning
9
+ * of the processing the settings and rules defined for the particular importer are copied to the
10
+ * initial state of the process. During the processing we may ask questions and add more information
11
+ * to the process.
12
+ *
13
+ * So the structure of the configration is
14
+ * ```json
15
+ * {
16
+ * "language": "fi",
17
+ * "currency": "EUR",
18
+ * ...
19
+ * "account.income.currency.EUR": "1910",
20
+ * ...
21
+ * "rules": [...],
22
+ * "questions": {...},
23
+ * "answers": {...}
24
+ * }
25
+ * ```
26
+ * There are
27
+ * 1. Generic universal settings like *language* or *currency*.
28
+ * 2. Then there is an account and import setting configuration that has been possibly resolved during the import process
29
+ * by asking from user, but which will also apply universally afterwards and are copied to the future import
30
+ * configuration.
31
+ * 3. **Rules** section defines how to map segments to transfers.
32
+ * 4. **Question** section defines UI questions to resolve some cases, that always require user interaction and
33
+ * cannot be resolved automatically.
34
+ * 5. **Answers** section is a collection of responses to questions stored by each segment. They are not universally
35
+ * copied to the importer, but are only relevant the current import only.
36
+ *
37
+ * ### Settings
38
+ *
39
+ * The following general settings are used
40
+ * - `currency` - A main currency of the bookkeeping database.
41
+ * - `language` - A translation language for the imported texts.
42
+ * - `tags.*.*.*` - A list of tags to be added for every transaction descriptions. Also some specific tags
43
+ * can be specified, since `*.*.*` uses the same convention than account configurations.
44
+ *
45
+ * Accounts are defined as the following.
46
+ * - `account.<reason>.<type>.<asset>` - Defines the account number to be used for the given purpose.
47
+ * Parts can be `'*'` to allow any purpose. Otherwise they are
48
+ * explained in more detail in {@link TransferAnalyzer}.
49
+ *
50
+ * Miscellaneous optional settings:
51
+ * - `isTradeFeePartOfTotal` If set to `true`, assume that trading fee is included in the total.
52
+ * Otherwise it is assumed to be paid on the top of the total.
53
+ * - `recordDeposits` If set to false, skip deposits.
54
+ * - `recordWithdrawals` If set to false, skip withdrawls.
55
+ * - `allowShortSelling` If set, allow short selling, i.e. selling assets we don't have.
56
+ *
57
+ * #### Example
58
+ * ```json
59
+ * {
60
+ * "currency": "EUR",
61
+ * "language": "en",
62
+ * "tags.*.*.*": ["Lynx"],
63
+ * "account.deposit.currency.EUR": "1918",
64
+ * "account.deposit.external.EUR": "9999",
65
+ * "account.withdrawal.currency.EUR": "1918",
66
+ * "account.withdrawal.external.EUR": "9999",
67
+ * "account.expense.statement.INTEREST_EXPENSE": "9550",
68
+ * "account.expense.currency.EUR": "1918",
69
+ *
70
+ * "rules": [],
71
+ * "questions": [],
72
+ * "answers": {}
73
+ * }
74
+ * ```
75
+ *
76
+ * ### Rules
77
+ *
78
+ * Rules sections is a list of rule definitions of form
79
+ * ```json
80
+ * {
81
+ * "name": "Name of the rule",
82
+ * "filter": "<expression>",
83
+ * "comment": "<optional description>",
84
+ * "options": {
85
+ * <optional flags>
86
+ * },
87
+ * "result": [
88
+ * <transfer1>, <transfer2>...
89
+ * ]
90
+ * }
91
+ * ```
92
+ * The *name* is any string describing the rule. Rules are used so that each segment resulting from the segmentation
93
+ * step are handled in the order of their timestamps. Lines belonging to the segment are offered one by one to the
94
+ * *filter* expression and if returning true, the entries in *result* are concatenated together. Each entry in the
95
+ * result is a *transfer description*.
96
+ *
97
+ * The filtering and result expressions has various variables set during the processing. All variables from
98
+ * the segmentation is included. Typically they are the same as the column names in the CSV file for example.
99
+ * See {@link TransactionRules.classifyLines} for other variables available.
100
+ *
101
+ * The structure of transfers are explained in {@link TransferAnalyzer}.
102
+ *
103
+ * The syntax of the filter and result is explained in {@link RulesEngine}.
104
+ *
105
+ * Currently one one boolean option is supported: `singleMatch` which means that matching any of the lines in the
106
+ * segment suffices and the parsing result is returned immediately when matching rule is found. The rest of the
107
+ * lines are ignored. It is useful when for example using `sum(lines, 'field')` to gather values from all lines
108
+ * of the segment at once.
109
+ *
110
+ * ### Questions
111
+ *
112
+ * There are situation, where importer cannot deduct some part of the transfer automatically. In that case we can
113
+ * define a question that needs to be answered every time, when the matching rule has been found. For example
114
+ * we may determine based on the transaction data that it is related to computers but we want to know the exact
115
+ * type of the purchase. Then we can define a question
116
+ * ```json
117
+ * {
118
+ * "name": "Computer purchase",
119
+ * "label": "What category is the purchase",
120
+ * "ask": {
121
+ * "Hardware equipment": "HARDWARE",
122
+ * "Software": "SOFTWARE"
123
+ * }
124
+ * },
125
+ * ```
126
+ *
127
+ * The question can be used in the transfer as explained in {@link TransferAnalyzer}.
128
+ *
129
+ * Different question types are documented in {@link TransactionUI.parseQuery}.
130
+ *
131
+ * ### Answers
132
+ *
133
+ * This section collects answers given earlier during the processing. They are grouped per segment ID per transfer.
134
+ * For example
135
+ * ```json
136
+ * "d3e89d9af37dda4609bed94770fc5c52be946175": {
137
+ * "type": "HARDWARE"
138
+ * },
139
+ * ```
140
+ * It may contain also complete transaction definition, which will override all parsing
141
+ * ```
142
+ * "581e46d024678ddcddc01ae36369bf6fc54f16b2": {
143
+ * "transfers": [
144
+ * {
145
+ * "data": {
146
+ * "text": "Payment for something"
147
+ * },
148
+ * "type": "account",
149
+ * "asset": "8650",
150
+ * "amount": 59.27,
151
+ * "reason": "expense"
152
+ * },
153
+ * {
154
+ * "type": "account",
155
+ * "asset": "3020",
156
+ * "amount": -59.27,
157
+ * "reason": "expense"
158
+ * }
159
+ * ]
160
+ * }
161
+ * ```
162
+ * There is also a global answer section applied to all imports. If an asset has changed its name, it can be
163
+ * stored like this in the empty segment ID:
164
+ * ```
165
+ * "": {
166
+ * "asset-renaming": [
167
+ * {
168
+ * "date": "<YYYY-MM-DD>"
169
+ * "type": "stock",
170
+ * "old": "<OLD ASSET>"
171
+ * "new": "<NEW ASSET>"
172
+ * }
173
+ * ]
174
+ * }
175
+ * }
176
+ * ```
177
+ */
178
+ export class TransactionRules {
179
+ // TODO: Could also define extension from ProcessConfig configuration type definition and start building precise description.
180
+ // Most of the use cases in files of this dir, are referring to the import configuration.
181
+ handler;
182
+ UI;
183
+ cache;
184
+ constructor(handler) {
185
+ this.handler = handler;
186
+ this.UI = handler.UI;
187
+ this.clearCache();
188
+ }
189
+ /**
190
+ * Clear colleciton of named UI questions.
191
+ */
192
+ clearCache() {
193
+ this.cache = {};
194
+ }
195
+ /**
196
+ * Handle query caching.
197
+ * @param query
198
+ *
199
+ * If query has no name, we do nothing. Return query itself.
200
+ * Otherwise it depends if query has anything else but name.
201
+ * For name-only we look from cache and throw error if not found.
202
+ * Otherwise it is saved to cache.
203
+ */
204
+ cachedQuery(query) {
205
+ if (query.name) {
206
+ if (isUIQueryRef(query)) {
207
+ if (!this.cache[query.name]) {
208
+ throw new BadState(`Cannot use a reference to question '${query.name}' before it is defined.`);
209
+ }
210
+ return this.cache[query.name];
211
+ }
212
+ else {
213
+ this.cache[query.name] = query;
214
+ }
215
+ }
216
+ return query;
217
+ }
218
+ /**
219
+ * Collect answers for questions or if not yet given, throw new query to get them.
220
+ * @param questions
221
+ * @param config
222
+ */
223
+ async getAnswers(segmentId, lines, questions, config) {
224
+ // Check existing answers.
225
+ const language = config.language;
226
+ const results = {};
227
+ const missing = [];
228
+ for (let [variable, query] of Object.entries(questions)) {
229
+ query = this.cachedQuery(query);
230
+ const answers = config.answers || {};
231
+ if (segmentId in answers && variable in answers[segmentId]) {
232
+ results[variable] = answers[segmentId][variable];
233
+ }
234
+ else {
235
+ missing.push(await this.UI.parseQuery(`answer.${segmentId}.${variable}`, query, language));
236
+ }
237
+ }
238
+ // If not all answered, ask them.
239
+ if (missing.length) {
240
+ const element = {
241
+ type: 'flat',
242
+ elements: [
243
+ await this.UI.describeLines(lines, language),
244
+ ...missing,
245
+ await this.UI.submit('Continue', 2, language)
246
+ ]
247
+ };
248
+ this.UI.throw(element);
249
+ }
250
+ return results;
251
+ }
252
+ /**
253
+ * Use the rules from the configuration to classify importer transfer lines.
254
+ * @param lines
255
+ * @param config
256
+ * @returns
257
+ *
258
+ * Each rule is checked against each line.
259
+ * For evaluation of the filter expression, all column values of the segment are provided.
260
+ * In addition the following special variables are provided:
261
+ * * `config` - all configuration variables
262
+ * * `rule` - the current rule we are evaluating
263
+ * * `options` - the options of the current rule we are evaluating
264
+ * * `text` - original text of the corresponding line
265
+ * * `lineNumber` - original line number of the corresponding line
266
+ * If the filter match is found, then questions are provided to UI unless already
267
+ * answered. The reponses to the questions are passed to the any further evaluations.
268
+ */
269
+ async classifyLines(lines, config, segment) {
270
+ let transfers = [];
271
+ const rules = config.rules || [];
272
+ const engine = new RulesEngine();
273
+ let matched = false;
274
+ // Make private copy.
275
+ config = clone(config);
276
+ // Cache questions.
277
+ if (config.questions) {
278
+ config.questions.forEach(q => this.cachedQuery(q));
279
+ }
280
+ debug('RULES', '============================================================');
281
+ debug('RULES', 'Classifying segment', segment.id);
282
+ debug('RULES', '============================================================');
283
+ // Check if we have explicit answer for the segment.
284
+ const explicit = await this.checkExplicitResult(segment, config.answers);
285
+ if (explicit) {
286
+ return explicit;
287
+ }
288
+ try {
289
+ const lineValues = lines.map(line => clone(line.columns));
290
+ let index = 0;
291
+ for (const line of lines) {
292
+ let lineHasMatch = false;
293
+ const columns = lineValues[index++];
294
+ debug('RULES', '-----------------------------------------------------');
295
+ debug('RULES', line.text);
296
+ debug('RULES', '-----------------------------------------------------');
297
+ debug('RULES', columns);
298
+ // Find the rule that has matching filter expression.
299
+ for (let rule of rules) {
300
+ rule = clone(rule);
301
+ const values = {
302
+ ...columns,
303
+ lines: lineValues,
304
+ config,
305
+ rule,
306
+ options: rule.options || {},
307
+ text: line.text,
308
+ lineNumber: line.line
309
+ };
310
+ const singleMatch = rule.options && rule.options.singleMatch;
311
+ if (engine.eval(rule.filter, values)) {
312
+ debug('RULES', 'Rule', rule.name, 'with filter', rule.filter, 'matches.');
313
+ matched = true;
314
+ lineHasMatch = true;
315
+ // Check that result is defined.
316
+ if (!rule.result) {
317
+ throw new BadState(`The rule ${JSON.stringify(rule)} has no result section.`);
318
+ }
319
+ // We have found the match. Now construct transfers from the rule.
320
+ const answers = rule.questions ? await this.getAnswers(segment.id, lines, rule.questions, config) : {};
321
+ // Replace cached queries to the variables passed to the rule engine.
322
+ if (rule.questions) {
323
+ const q = rule.questions;
324
+ Object.keys(q).forEach(key => {
325
+ q[key] = this.cachedQuery(q[key]);
326
+ });
327
+ }
328
+ transfers = transfers.concat(this.parseResults(engine, lines, rule, values, answers));
329
+ // Continue to next line unless single match.
330
+ if (singleMatch) {
331
+ return await this.postProcess(segment, {
332
+ type: 'transfers',
333
+ transfers
334
+ });
335
+ }
336
+ break;
337
+ } // if (engine.eval(rule.filter, values))
338
+ } // for (let rule of rules)
339
+ if (!lineHasMatch) {
340
+ await this.UI.throwNoFilterMatchForLine(lines, config, this.handler.importOptions);
341
+ }
342
+ } // for (const line of lines)
343
+ if (transfers.length > 0) {
344
+ return await this.postProcess(segment, {
345
+ type: 'transfers',
346
+ transfers
347
+ });
348
+ }
349
+ }
350
+ catch (err) {
351
+ if (err instanceof RuleParsingError) {
352
+ await this.throwErrorRetry(err, config.language);
353
+ }
354
+ else {
355
+ throw err;
356
+ }
357
+ }
358
+ // Decide the error when passing through without finding an answer.
359
+ if (matched) {
360
+ throw new Error(`Found matches but the result list is empty for ${JSON.stringify(lines)}.`);
361
+ }
362
+ throw new Error(`Could not find rules matching ${JSON.stringify(lines)}.`);
363
+ }
364
+ /**
365
+ * Check if there is an explicit answer already that needs to be returned for this segment.
366
+ */
367
+ async checkExplicitResult(segment, ans) {
368
+ if (ans && segment.id) {
369
+ const answers = ans;
370
+ if (answers[segment.id]) {
371
+ // Explicit transfer.
372
+ if (answers[segment.id].transfers) {
373
+ return await this.postProcess(segment, {
374
+ type: 'transfers',
375
+ transfers: answers[segment.id].transfers
376
+ });
377
+ }
378
+ // Explicit skipping.
379
+ if (answers[segment.id].skip) {
380
+ return {
381
+ type: 'transfers',
382
+ transfers: [],
383
+ transactions: [
384
+ {
385
+ date: segment.time,
386
+ segmentId: segment.id,
387
+ entries: [],
388
+ executionResult: 'skipped'
389
+ }
390
+ ]
391
+ };
392
+ }
393
+ }
394
+ }
395
+ }
396
+ /**
397
+ * Compute results from a rule.
398
+ */
399
+ parseResults(engine, lines, rule, values, answers) {
400
+ const transfers = [];
401
+ const results = 'length' in rule.result ? rule.result : [rule.result];
402
+ let index = 0;
403
+ if (results.length === 0) {
404
+ debug('RULES', 'Result: NONE');
405
+ }
406
+ for (const result of results) {
407
+ debug('RULES', `Result[${index}]:`);
408
+ const transfer = {};
409
+ // Collect fields evaluating directly from formula.
410
+ for (const [name, formula] of Object.entries(result)) {
411
+ if (name in transfer) {
412
+ warning(`A rule '${rule.name}' resulted duplicate value in formula '${formula}' for the field '${name}''. Already having ${JSON.stringify(transfer)}.`);
413
+ }
414
+ else {
415
+ transfer[name] = engine.eval(formula, { ...values, ...answers });
416
+ debug('RULES', ` ${name} =`, JSON.stringify(transfer[name]));
417
+ }
418
+ }
419
+ // Verify condition before adding.
420
+ if (transfer.if === undefined || engine.eval(transfer.if, { ...values, ...answers })) {
421
+ // Catch bad results from formulas. Hit two jokers as well.
422
+ if (isAssetTransfer(transfer) && transfer.asset !== 'undefined' && transfer.asset !== 'null') {
423
+ transfers.push(transfer);
424
+ if (transfer.if) {
425
+ debug('RULES', ' Accepted condition', transfer.if);
426
+ }
427
+ }
428
+ else {
429
+ console.log('Failing lines:');
430
+ console.dir(lines, { depth: null });
431
+ console.log('Matching rule:');
432
+ console.dir(rule, { depth: null });
433
+ throw new BadState(`Asset transfer ${JSON.stringify(transfer)} is incomplete.`);
434
+ }
435
+ }
436
+ else {
437
+ debug('RULES', ' Dropped due to condition', transfer.if);
438
+ }
439
+ index++;
440
+ }
441
+ return transfers;
442
+ }
443
+ /**
444
+ * Throw UI error with retry option.
445
+ */
446
+ async throwErrorRetry(err, lang) {
447
+ error(`Parsing error in expression '${err.expression}': ${err.message}`);
448
+ if (err.variables.rule) {
449
+ error(`While parsig rule ${JSON.stringify(err.variables.rule)}`);
450
+ }
451
+ if (err.variables && err.variables.text) {
452
+ error(`Failure in line ${err.variables.lineNumber}: ${err.variables.text}`);
453
+ const variables = clone(err.variables);
454
+ delete variables.config;
455
+ delete variables.rule;
456
+ delete variables.text;
457
+ delete variables.lineNumber;
458
+ error(`Variables when processing the line: ${JSON.stringify(variables)}.`);
459
+ }
460
+ // For parsing errors we can expect user editing configuration and then retrying.
461
+ const msg = (await this.UI.getTranslation('Parsing error in expression `{expr}`: {message}', lang)).replace('{expr}', err.expression).replace('{message}', err.message);
462
+ await this.UI.throwErrorRetry(msg, lang);
463
+ }
464
+ /**
465
+ * Check for needed adjustments like VAT before returning the result.
466
+ * @param result
467
+ * @returns
468
+ */
469
+ async postProcess(segment, result) {
470
+ // Find currency.
471
+ const vatReasons = new Set(['dividend', 'income', 'expense']);
472
+ const currencies = new Set(result.transfers.filter(t => vatReasons.has(t.reason) && t.type === 'currency').map(t => t.asset));
473
+ if (currencies.size > 1) {
474
+ throw new SystemError(`Not yet able to sort out VAT for multiple different currencies in ${JSON.stringify(result.transfers)}`);
475
+ }
476
+ // If no currencies, assume no VAT.
477
+ if (currencies.size) {
478
+ const currency = [...currencies][0];
479
+ // Add VAT where needed.
480
+ const vatTransfers = [];
481
+ for (const transfer of result.transfers) {
482
+ let vatPct;
483
+ if (transfer.data && 'vat' in transfer.data) {
484
+ vatPct = transfer.data.vat;
485
+ }
486
+ else {
487
+ vatPct = await this.handler.getVAT(segment.time, transfer, currency);
488
+ }
489
+ const vatValue = (transfer.data && 'vatValue' in transfer.data) ? transfer.data.vatValue : null;
490
+ if ((vatPct || vatValue) && transfer.amount) {
491
+ const oldAmount = Math.round(transfer.amount * 100);
492
+ const newAmount = vatValue !== null && vatValue !== undefined ? Math.round(oldAmount - vatValue * 100) : Math.round(transfer.amount * 100 / (1 + vatPct / 100));
493
+ transfer.amount = newAmount / 100;
494
+ const vat = oldAmount - newAmount;
495
+ const vatEntry = {
496
+ reason: 'tax',
497
+ type: 'statement',
498
+ asset: vat > 0 ? 'VAT_FROM_PURCHASES' : 'VAT_FROM_SALES',
499
+ amount: vat / 100,
500
+ data: {
501
+ currency
502
+ }
503
+ };
504
+ if (transfer.tags) {
505
+ vatEntry.tags = transfer.tags;
506
+ }
507
+ vatTransfers.push(vatEntry);
508
+ }
509
+ }
510
+ result.transfers = result.transfers.concat(vatTransfers);
511
+ }
512
+ // Bundle tags if given as an object.
513
+ for (let i = 0; i < result.transfers.length; i++) {
514
+ if ('tags' in result.transfers[i] && typeof result.transfers[i].tags === 'object' && result.transfers[i].tags?.length === undefined && result.transfers[i].tags !== null) {
515
+ const tags = result.transfers[i].tags;
516
+ result.transfers[i].tags = Object.keys(tags).filter(t => !!tags[t]).sort();
517
+ }
518
+ }
519
+ return result;
520
+ }
521
+ }
522
+ //# sourceMappingURL=TransactionRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactionRules.js","sourceRoot":"","sources":["../../../../src/import/TransactionRules.ts"],"names":[],"mappings":"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"}