@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,241 @@
1
+ import { NO_SEGMENT } from '@dataplug/tasenor-common';
2
+ import { InvalidFile, NotImplemented, TransactionImportHandler } from '@dataplug/tasenor-common-node';
3
+ // Store the latest transactoin ID
4
+ let ref;
5
+ /**
6
+ * Import implementation for TITO format.
7
+ *
8
+ * Based on https://www.nordea.fi/Images/146-84478/xml_tiliote.pdf
9
+ */
10
+ export class TITOHandler extends TransactionImportHandler {
11
+ constructor() {
12
+ super('TITOImport');
13
+ this.importOptions = {
14
+ parser: 'custom',
15
+ numericFields: ['Tapahtuman rahamäärä', 'Tietuetunnus', 'Panot Summa', 'Otot Summa', 'Panot Kappalemäärä', 'Otot Kappalemäärä', 'Tiliotteen tietueiden lukumäärä', 'Tilin limiitti'],
16
+ requiredFields: ['Tietuetunnus', 'Viite', 'Seliteteksti'],
17
+ insignificantFields: ['Tietuetunnus', 'Tapahtuman numero', 'Tapahtumatunnus', 'Koodi', 'Kuittikoodi', 'Välitystapa', 'Nimen lähde', 'Tili muuttunut -tieto', 'Lomakkeen numero', 'Tasotunnus'],
18
+ sharedFields: ['Toimeksiantajan tieto-1', 'Toimeksiantajan tieto-2'],
19
+ textField: 'Seliteteksti',
20
+ totalAmountField: 'Tapahtuman rahamäärä',
21
+ custom: {
22
+ splitToLines: (s) => {
23
+ const ret = [];
24
+ for (let i = 0; i < s.length;) {
25
+ if (s[i] !== 'T') {
26
+ throw new InvalidFile('Parsing a file failed. Missing "T" in the beginning of the record.');
27
+ }
28
+ const len = parseInt(s.substring(i + 3, i + 6));
29
+ const text = s.substring(i, i + len)
30
+ .replace(/\]/g, 'Å')
31
+ .replace(/\[/g, 'Ä')
32
+ .replace(/\\/g, 'Ö')
33
+ .replace(/\}/g, 'å')
34
+ .replace(/\{/g, 'ä')
35
+ .replace(/\|/g, 'ö');
36
+ ret.push(text);
37
+ i += len;
38
+ while (s.charCodeAt(i) === 10 || s.charCodeAt(i) === 13) {
39
+ i++;
40
+ }
41
+ }
42
+ return ret;
43
+ },
44
+ splitToColumns: (s) => {
45
+ if (s[0] !== 'T') {
46
+ throw new InvalidFile('Parsing a line failed. Missing "T" in the beginning of the line.');
47
+ }
48
+ const code = s.substring(1, 3);
49
+ let columns;
50
+ let extras;
51
+ switch (code) {
52
+ // Header line.
53
+ case '00':
54
+ ref = undefined;
55
+ return {
56
+ Tietuetunnus: code,
57
+ ...this.parseFixedLength(s.substring(6), {
58
+ Versionumero: 3,
59
+ Tilinumero: 14,
60
+ 'Tiliotteen numero': 3,
61
+ Tiliotekausi: 12,
62
+ Muodostumisaika: 10,
63
+ Asiakastunnus: 17,
64
+ 'Alkusaldon pvm': 6,
65
+ 'Tiliotteen alkusaldo': 19,
66
+ 'Tiliotteen tietueiden lukumäärä': 6,
67
+ 'Tilin valuutan tunnus': 3,
68
+ 'Tilin nimi': 30,
69
+ 'Tilin limiitti': 18,
70
+ 'Tilin omistajan nimi': 35,
71
+ 'Yhteydenottotieto-1': 40,
72
+ 'Yhteydenottotieto-2': 40,
73
+ 'Pankkikohtaista tietoa-1': 30,
74
+ 'Pankkikohtaista tietoa-2': 30,
75
+ }, {
76
+ Tiliotekausi: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)} 20${s.substring(6, 8)}-${s.substring(8, 10)}-${s.substring(10, 12)}`,
77
+ Muodostumisaika: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)} ${s.substring(6, 8)}:${s.substring(8, 10)}:00`,
78
+ 'Alkusaldon pvm': (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)}`,
79
+ 'Tiliotteen alkusaldo': (s) => `${parseInt(s) / 100}`,
80
+ 'Tiliotteen tietueiden lukumäärä': (s) => `${parseInt(s)}`,
81
+ 'Tilin limiitti': (s) => `${parseInt(s) / 100}`,
82
+ })
83
+ };
84
+ // Basic transaction
85
+ case '10':
86
+ columns = {
87
+ Tietuetunnus: code,
88
+ ...this.parseFixedLength(s.substring(6), {
89
+ 'Tapahtuman numero': 6,
90
+ Arkistointitunnus: 18,
91
+ Kirjauspäivä: 6,
92
+ Arvopäivä: 6,
93
+ Maksupäivä: 6,
94
+ Tapahtumatunnus: 1,
95
+ Koodi: 3,
96
+ Seliteteksti: 35,
97
+ 'Tapahtuman rahamäärä': 19,
98
+ Kuittikoodi: 1,
99
+ Välitystapa: 1,
100
+ 'Saaja/Maksaja': 35,
101
+ 'Nimen lähde': 1,
102
+ 'Saajan tili': 14,
103
+ 'Tili muuttunut -tieto': 1,
104
+ Viite: 20,
105
+ 'Lomakkeen numero': 8,
106
+ Tasotunnus: 1,
107
+ }, {
108
+ Kirjauspäivä: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)}`,
109
+ Arvopäivä: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)}`,
110
+ Maksupäivä: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)}`,
111
+ Viite: (s) => s.replace(/^0+/, ''),
112
+ 'Tapahtuman rahamäärä': (s) => `${parseInt(s) / 100}`,
113
+ })
114
+ };
115
+ ref = columns.Arkistointitunnus;
116
+ return columns;
117
+ // Additional information.
118
+ case '11':
119
+ columns = {
120
+ Tietuetunnus: code,
121
+ ...this.parseFixedLength(s.substring(6), {
122
+ 'Lisätiedon tyyppi': 2,
123
+ Lisätieto: 999999
124
+ }, {})
125
+ };
126
+ if (ref) {
127
+ columns['Edellinen Arkistointitunnus'] = ref;
128
+ }
129
+ extras = columns['Lisätieto'];
130
+ switch (columns['Lisätiedon tyyppi']) {
131
+ case '00':
132
+ Object.assign(columns, {
133
+ ...this.parseFixedLength(extras, {
134
+ 'Viesti-1': 35,
135
+ 'Viesti-2': 35,
136
+ 'Viesti-3': 35,
137
+ 'Viesti-4': 35,
138
+ 'Viesti-5': 35,
139
+ 'Viesti-6': 35,
140
+ 'Viesti-7': 35,
141
+ 'Viesti-8': 35,
142
+ 'Viesti-9': 35,
143
+ 'Viesti-10': 35,
144
+ 'Viesti-11': 35,
145
+ 'Viesti-12': 35,
146
+ }, {})
147
+ });
148
+ break;
149
+ case '03':
150
+ Object.assign(columns, {
151
+ ...this.parseFixedLength(extras, {
152
+ 'Kortin numero': 19,
153
+ Tyhjää: 1,
154
+ 'Kaupan arkistoviite': 14,
155
+ }, {})
156
+ });
157
+ break;
158
+ case '06':
159
+ Object.assign(columns, {
160
+ ...this.parseFixedLength(extras, {
161
+ 'Toimeksiantajan tieto-1': 35,
162
+ 'Toimeksiantajan tieto-2': 35,
163
+ }, {
164
+ 'Toimeksiantajan tieto-1': (s) => s.replace(/^0+/, ''),
165
+ 'Toimeksiantajan tieto-2': (s) => s.replace(/^0+/, ''),
166
+ })
167
+ });
168
+ break;
169
+ case '11':
170
+ Object.assign(columns, {
171
+ ...this.parseFixedLength(extras, {
172
+ 'Maksajan viite': 35,
173
+ }, {})
174
+ });
175
+ break;
176
+ default:
177
+ throw new NotImplemented(`Parsing a record of subtype '${columns['Lisätiedon tyyppi']}' is not implemented for record type 'T11'.`);
178
+ }
179
+ return columns;
180
+ // Balance record.
181
+ case '40':
182
+ return {
183
+ Tietuetunnus: code,
184
+ ...this.parseFixedLength(s.substring(6), {
185
+ Kirjauspäivä: 6,
186
+ 'Kirjauspäivän loppusaldo': 19,
187
+ 'Käytettävissä oleva saldo': 19,
188
+ }, {
189
+ Kirjauspäivä: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)}`,
190
+ 'Kirjauspäivän loppusaldo': (s) => `${parseInt(s) / 100}`,
191
+ 'Käytettävissä oleva saldo': (s) => `${parseInt(s) / 100}`,
192
+ })
193
+ };
194
+ // Balance record.
195
+ case '50':
196
+ return {
197
+ Tietuetunnus: code,
198
+ ...this.parseFixedLength(s.substring(6), {
199
+ 'Jakson tunnus': 1,
200
+ Jaksopäivä: 6,
201
+ 'Panot Kappalemäärä': 8,
202
+ 'Panot Summa': 19,
203
+ 'Otot Kappalemäärä': 8,
204
+ 'Otot Summa': 19,
205
+ }, {
206
+ Jaksopäivä: (s) => `20${s.substring(0, 2)}-${s.substring(2, 4)}-${s.substring(4, 6)}`,
207
+ 'Panot Summa': (s) => `${parseInt(s) / 100}`,
208
+ 'Panot Kappalemäärä': (s) => `${parseInt(s)}`,
209
+ 'Otot Summa': (s) => `${parseInt(s) / 100}`,
210
+ 'Otot Kappalemäärä': (s) => `${parseInt(s)}`,
211
+ })
212
+ };
213
+ // Notification record.
214
+ case '70':
215
+ return {
216
+ Tietuetunnus: code,
217
+ ...this.parseFixedLength(s.substring(6), {
218
+ 'Pankkiryhmän tunnus': 3,
219
+ Tiedote: 80 * 6,
220
+ }, {})
221
+ };
222
+ default:
223
+ throw new NotImplemented(`Parsing a record of type 'T${code}' is not implemented.`);
224
+ }
225
+ return {};
226
+ }
227
+ }
228
+ };
229
+ }
230
+ canHandle(file) {
231
+ return file.startsWith('T00322100');
232
+ }
233
+ time(line) {
234
+ const date = line.columns['Kirjauspäivä'] || line.columns['Jaksopäivä'] || undefined;
235
+ return date ? new Date(date) : undefined;
236
+ }
237
+ segmentId(line) {
238
+ return line.columns.Arkistointitunnus || line.columns['Edellinen Arkistointitunnus'] || NO_SEGMENT;
239
+ }
240
+ }
241
+ //# sourceMappingURL=TITOHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TITOHandler.js","sourceRoot":"","sources":["../../../../../../tasenor-common-plugins/src/TITOImport/backend/TITOHandler.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('jestconfig')
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@tasenor/common-node",
3
+ "version": "1.9.16",
4
+ "description": "Common Node-parts of Tasenor project",
5
+ "main": "src/index.ts",
6
+ "types": "src/index.ts",
7
+ "repository": "git@github.com:dataplugoy/tasenor-bookkeeper.git",
8
+ "author": "Tommi Ronkainen <tommi.ronkainen@gmail.com>",
9
+ "license": "MIT",
10
+ "dependencies": {
11
+ "@vscode/sqlite3": "5.1.6-vscode",
12
+ "argparse": "^2.0.1",
13
+ "axios": "0.26.0",
14
+ "bcrypt": "^5.1.0",
15
+ "chardet": "^1.6.0",
16
+ "clone": "^2.1.2",
17
+ "cors": "^2.8.5",
18
+ "csv-parse": "^5.4.0",
19
+ "dayjs": "1.10.8",
20
+ "dot-object": "^2.1.4",
21
+ "express": "^4.18.2",
22
+ "fast-glob": "^3.3.0",
23
+ "form-data": "^4.0.0",
24
+ "git-url-parse": "^13.1.0",
25
+ "helmet": "^7.0.0",
26
+ "json2csv": "6.0.0-alpha.2",
27
+ "jsonwebtoken": "^9.0.1",
28
+ "knex": "^2.5.0",
29
+ "merge": "^2.1.1",
30
+ "mime-types": "^2.1.35",
31
+ "object-hash": "^3.0.0",
32
+ "pg": "^8.11.1",
33
+ "pg-types": "^4.0.1",
34
+ "simple-git": "^3.19.1",
35
+ "sprintf-js": "^1.1.2",
36
+ "sqlite3": "^5.1.6",
37
+ "tar": "^6.1.15",
38
+ "ts-opaque": "^3.0.1",
39
+ "@dataplug/tasenor-common": "npm:@tasenor/common@1.9.16"
40
+ },
41
+ "devDependencies": {
42
+ "@jest/globals": "^29.6.1",
43
+ "@types/jest": "^29.5.2",
44
+ "@types/jsonwebtoken": "^9.0.2",
45
+ "jest": "^29.6.1",
46
+ "ts-jest": "^29.1.1",
47
+ "typescript": "^5.1.6",
48
+ "jestconfig": "0.0.0",
49
+ "eslint-config-tasenor": "0.0.0",
50
+ "@dataplug/tasenor-testing": "npm:@tasenor/testing@1.9.16",
51
+ "tsconfig": "0.0.0"
52
+ },
53
+ "scripts": {
54
+ "ci": "pnpm run lint && pnpm run build && pnpm run test",
55
+ "build": "rm -rf dist && tsc",
56
+ "fix": "eslint --fix 'src/**/*.ts' 'tests/**/*.ts'",
57
+ "lint": "eslint 'src/**/*.ts' 'tests/**/*.ts'",
58
+ "test": "jest",
59
+ "watch": "jest --onlyChanged --watch",
60
+ "version": "jq .version < package.json"
61
+ }
62
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,267 @@
1
+ /* eslint-disable camelcase */
2
+ /**
3
+ * Command line interface utilities.
4
+ *
5
+ * @module tasenor-common-node/src/cli
6
+ */
7
+ import * as readline from 'readline'
8
+ import * as FormData from 'form-data'
9
+ import { ArgumentParser } from 'argparse'
10
+ import { HttpMethod, net, Url, Value, TokenPair, Token, log, HttpResponse, mute, waitPromise, note } from '@dataplug/tasenor-common'
11
+ import clone from 'clone'
12
+ import DbCommand from './commands/db'
13
+ import { Command, CommandArgumentDefault, CommandArguments } from './commands'
14
+ import AccountCommand from './commands/account'
15
+ import BalanceCommand from './commands/balance'
16
+ import EntryCommand from './commands/entry'
17
+ import ImportCommand from './commands/import'
18
+ import PeriodCommand from './commands/period'
19
+ import ImporterCommand from './commands/importer'
20
+ import PluginCommand from './commands/plugin'
21
+ import ReportCommand from './commands/report'
22
+ import SettingsCommand from './commands/settings'
23
+ import StockCommand from './commands/stock'
24
+ import TagCommand from './commands/tag'
25
+ import TxCommand from './commands/tx'
26
+ import UserCommand from './commands/user'
27
+
28
+ let readlineInterface
29
+
30
+ /**
31
+ * Ask a question on the console and return answer.
32
+ * @param question
33
+ * @returns
34
+ */
35
+ function ask(question: string): Promise<string> {
36
+ if (!readlineInterface) {
37
+ readlineInterface = readline.createInterface({
38
+ input: process.stdin,
39
+ output: process.stdout
40
+ })
41
+ }
42
+ return new Promise((resolve) => {
43
+ readlineInterface.question(question ? `${question} ` : '>', (text) => { resolve(text) })
44
+ })
45
+ }
46
+
47
+ /**
48
+ * Exit hook that needs to be called if used functions in this library.
49
+ */
50
+ function exit() {
51
+ if (readlineInterface) readlineInterface.close()
52
+ }
53
+
54
+ /**
55
+ * An interface for accessing API.
56
+ */
57
+ export class CLIRunner {
58
+ user: string
59
+ password: string
60
+ api: Url
61
+ uiApi: Url
62
+ token: Token
63
+ commands: Record<string, Command>
64
+ originalArgs: string[]
65
+ args: CommandArguments
66
+
67
+ /**
68
+ * Execute HTTP request.
69
+ * @param method
70
+ * @param url
71
+ * @returns
72
+ */
73
+ async request(method: HttpMethod, url: string, data: Value | undefined | FormData): Promise<HttpResponse> {
74
+ const caller = net[method]
75
+ const fullUrl: Url = url.startsWith('/') ? `${this.api}${url}` as Url : `${this.api}/${url}` as Url
76
+ return this.doRequest(caller, fullUrl, data)
77
+ }
78
+
79
+ /**
80
+ * Execute HTTP request against UI API.
81
+ * @param method
82
+ * @param url
83
+ * @returns
84
+ */
85
+ async requestUi(method: HttpMethod, url: string, data: Value | undefined | FormData): Promise<HttpResponse> {
86
+ const caller = net[method]
87
+ const fullUrl: Url = url.startsWith('/') ? `${this.uiApi}${url}` as Url : `${this.uiApi}/${url}` as Url
88
+ return this.doRequest(caller, fullUrl, data)
89
+ }
90
+
91
+ /**
92
+ * Execute request with optional retries.
93
+ * @param caller
94
+ * @param fullUrl
95
+ * @param data
96
+ * @returns
97
+ */
98
+ async doRequest(caller, fullUrl, data) {
99
+ let result: HttpResponse | null = null
100
+ let error
101
+ const max = this.args.retry || 0
102
+ for (let i = -1; i < (max as number); i++) {
103
+ try {
104
+ result = await caller(fullUrl, data)
105
+ if (result && result.success) {
106
+ return result
107
+ }
108
+ error = new Error(JSON.stringify(result))
109
+ } catch (err) {
110
+ error = err
111
+ }
112
+ const delay = (i + 1) * 5
113
+ note(`Waiting for ${delay} seconds`)
114
+ await waitPromise(delay * 1000)
115
+ }
116
+
117
+ throw error
118
+ }
119
+
120
+ /**
121
+ * Log in if we don't have access token yet.
122
+ */
123
+ async login(): Promise<void> {
124
+
125
+ if (this.token) return
126
+
127
+ log(`Logging in to ${this.api} as ${this.user}`)
128
+ const resp = await this.request('POST', '/auth', { user: this.user, password: this.password } as unknown as Value)
129
+ if (resp.success && resp.data && resp.data instanceof Object) {
130
+ if ('token' in resp.data && 'refresh' in resp.data) {
131
+ const { token, refresh } = resp.data as unknown as { token: Token, refresh: Token }
132
+ this.configureApi(this.api, { token, refresh })
133
+ this.configureApi(this.uiApi, { token, refresh })
134
+ this.token = token
135
+ }
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Set up the API.
141
+ * @param tokens
142
+ */
143
+ configureApi(api: Url, tokens: TokenPair | undefined = undefined): void {
144
+ net.configure({ sites: { [api]: {} } })
145
+ if (tokens) {
146
+ net.setConf(api, 'token', tokens.token)
147
+ net.setConf(api, 'refreshToken', tokens.refresh)
148
+ }
149
+ }
150
+ }
151
+
152
+ /**
153
+ * A class implementing dynamic collection of commands that are automatically looked up when called.
154
+ */
155
+ export class CLI extends CLIRunner {
156
+
157
+ /**
158
+ * Scan commands and instantiate them to the collection.
159
+ * @param paths
160
+ */
161
+ constructor() {
162
+ super()
163
+
164
+ this.commands = {
165
+ account: new AccountCommand(this),
166
+ db: new DbCommand(this),
167
+ balance: new BalanceCommand(this),
168
+ entry: new EntryCommand(this),
169
+ import: new ImportCommand(this),
170
+ importer: new ImporterCommand(this),
171
+ period: new PeriodCommand(this),
172
+ plugin: new PluginCommand(this),
173
+ report: new ReportCommand(this),
174
+ settings: new SettingsCommand(this),
175
+ stock: new StockCommand(this),
176
+ tag: new TagCommand(this),
177
+ tx: new TxCommand(this),
178
+ user: new UserCommand(this)
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Insert defaults for the arguments.
184
+ * @param args
185
+ */
186
+ addDefaults(defaults: CommandArgumentDefault[]) {
187
+ for (const def of defaults) {
188
+ const { name, envName, defaultValue } = def
189
+ if (this.args[name] === undefined) {
190
+ this.args[name] = process.env[envName] || defaultValue
191
+ }
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Parse and execute the command.
197
+ */
198
+ async run(defaults: CommandArgumentDefault[] = [], explicitArgs: string[] = []): Promise<void> {
199
+ // Helper to extract arguments.
200
+ const pop = (args: CommandArguments, name: string): string => {
201
+ const ret = args[name]
202
+ delete args[name]
203
+ if (!ret) return ''
204
+ return typeof ret === 'string' ? ret : ret[0]
205
+ }
206
+
207
+ const parser: ArgumentParser = new ArgumentParser({
208
+ description: 'Tasenor command line tool'
209
+ })
210
+
211
+ parser.add_argument('command', { help: 'Command handling the operation', choices: Object.keys(this.commands) })
212
+ parser.add_argument('--debug', '-d', { help: 'If set, show logs for requests etc', action: 'store_true', required: false })
213
+ parser.add_argument('--json', { help: 'If set, show output as JSON', action: 'store_true', required: false })
214
+ parser.add_argument('--verbose', '-v', { help: 'If set, show more comprehensive output', action: 'store_true', required: false })
215
+ parser.add_argument('--user', { help: 'User email for logging in (use USERNAME env by default)', type: String, required: false })
216
+ parser.add_argument('--password', { help: 'User password for logging in (use PASSWORD env by default)', type: String, required: false })
217
+ parser.add_argument('--api', { help: 'The server base URL providing Bookkeeper API (use API env by default)', type: String, required: false })
218
+ parser.add_argument('--ui-api', { help: 'The server base URL providing Bookkeeper UI API (use UI_API env by default)', type: String, required: false })
219
+ parser.add_argument('--retry', { help: 'If given, retry this many times if network call fails', type: Number, required: false })
220
+
221
+ // Set up args.
222
+ this.originalArgs = explicitArgs.length ? clone(explicitArgs) : clone(process.argv.splice(2))
223
+
224
+ // Find the command and add its arguments.
225
+ let cmd: Command | undefined
226
+ for (let i = 0; i < this.originalArgs.length; i++) {
227
+ if (this.commands[this.originalArgs[i]]) {
228
+ cmd = this.commands[this.originalArgs[i]]
229
+ break
230
+ }
231
+ }
232
+
233
+ if (cmd) {
234
+ cmd.addArguments(parser)
235
+ }
236
+
237
+ // Collect and fix arguments.
238
+ this.args = parser.parse_args(this.originalArgs)
239
+
240
+ cmd?.setArgs(this.args)
241
+
242
+ this.addDefaults(defaults)
243
+ this.user = pop(this.args, 'user')
244
+ this.password = pop(this.args, 'password')
245
+ this.api = pop(this.args, 'api') as Url
246
+ this.uiApi = pop(this.args, 'ui_api') as Url
247
+ delete this.args.command
248
+ if (!this.args.debug) {
249
+ mute()
250
+ }
251
+
252
+ // Configure net APIs.
253
+ if (this.api) {
254
+ this.configureApi(this.api)
255
+ }
256
+ if (this.uiApi) {
257
+ this.configureApi(this.uiApi)
258
+ }
259
+
260
+ cmd && await cmd.run()
261
+ }
262
+ }
263
+
264
+ export const cli = {
265
+ ask,
266
+ exit
267
+ }
@@ -0,0 +1,69 @@
1
+ /* eslint-disable camelcase */
2
+ import { log, AccountModelData } from '@dataplug/tasenor-common'
3
+ import { Command } from '.'
4
+ import { ArgumentParser } from 'argparse'
5
+
6
+ class AccountCommand extends Command {
7
+
8
+ addArguments(parser: ArgumentParser): void {
9
+ const sub = parser.add_subparsers()
10
+
11
+ const ls = sub.add_parser('ls', { help: 'List all accounts' })
12
+ ls.set_defaults({ subCommand: 'ls' })
13
+ ls.add_argument('db', { help: 'Name of the database' })
14
+
15
+ const rm = sub.add_parser('rm', { help: 'Delete an account' })
16
+ rm.set_defaults({ subCommand: 'rm' })
17
+ rm.add_argument('db', { help: 'Name of the database' })
18
+ rm.add_argument('id', { help: 'ID of the account' })
19
+
20
+ const create = sub.add_parser('create', { help: 'Create an account' })
21
+ create.set_defaults({ subCommand: 'create' })
22
+ create.add_argument('db', { help: 'Name of the database' })
23
+ create.add_argument('language', { help: 'Account language' })
24
+ create.add_argument('currency', { help: 'Account currency' })
25
+ create.add_argument('type', { help: 'Account type' })
26
+ create.add_argument('number', { help: 'Account number' })
27
+ create.add_argument('name', { help: 'Account name' })
28
+ create.add_argument('data', { help: 'Additional account data in JSON format', nargs: '?' })
29
+ }
30
+
31
+ async ls() {
32
+ const { db } = this.args
33
+ const resp = await this.get(`/db/${db}/account`)
34
+ this.out('account', resp)
35
+ }
36
+
37
+ print(data: AccountModelData[]): void {
38
+ for (const account of data.sort((a, b) => (a.id || 0) - (b.id || 0))) {
39
+ const { id, number, name, type, language, currency, data } = account
40
+ console.log(`#${id} [${language} ${currency} ${type}] ${number} ${name} ${Object.keys(data).length ? JSON.stringify(data) : ''}`)
41
+ }
42
+ }
43
+
44
+ async rm() {
45
+ const { db, id } = this.args
46
+ await this.delete(`/db/${db}/account/${id}`)
47
+ log(`Account ${id} deleted successfully.`)
48
+ }
49
+
50
+ async create() {
51
+ const { db, number, name, type, language, currency, data } = this.args
52
+ const params = {
53
+ number,
54
+ name,
55
+ type,
56
+ language,
57
+ currency,
58
+ data: data ? await this.jsonData(data) : {}
59
+ }
60
+ await this.post(`/db/${db}/account`, params)
61
+ log(`Account ${number} ${name} created successfully.`)
62
+ }
63
+
64
+ async run() {
65
+ await this.runBy('subCommand')
66
+ }
67
+ }
68
+
69
+ export default AccountCommand