@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.
- package/.eslintrc.js +4 -0
- package/LICENSE +21 -0
- package/dist/tasenor-common-node/src/cli.d.ts +81 -0
- package/dist/tasenor-common-node/src/cli.js +242 -0
- package/dist/tasenor-common-node/src/cli.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/account.d.ts +12 -0
- package/dist/tasenor-common-node/src/commands/account.js +58 -0
- package/dist/tasenor-common-node/src/commands/account.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/balance.d.ts +11 -0
- package/dist/tasenor-common-node/src/commands/balance.js +117 -0
- package/dist/tasenor-common-node/src/commands/balance.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/db.d.ts +14 -0
- package/dist/tasenor-common-node/src/commands/db.js +69 -0
- package/dist/tasenor-common-node/src/commands/db.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/entry.d.ts +13 -0
- package/dist/tasenor-common-node/src/commands/entry.js +106 -0
- package/dist/tasenor-common-node/src/commands/entry.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/import.d.ts +17 -0
- package/dist/tasenor-common-node/src/commands/import.js +140 -0
- package/dist/tasenor-common-node/src/commands/import.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/importer.d.ts +13 -0
- package/dist/tasenor-common-node/src/commands/importer.js +71 -0
- package/dist/tasenor-common-node/src/commands/importer.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/index.d.ts +191 -0
- package/dist/tasenor-common-node/src/commands/index.js +482 -0
- package/dist/tasenor-common-node/src/commands/index.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/period.d.ts +12 -0
- package/dist/tasenor-common-node/src/commands/period.js +48 -0
- package/dist/tasenor-common-node/src/commands/period.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/plugin.d.ts +15 -0
- package/dist/tasenor-common-node/src/commands/plugin.js +78 -0
- package/dist/tasenor-common-node/src/commands/plugin.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/report.d.ts +11 -0
- package/dist/tasenor-common-node/src/commands/report.js +96 -0
- package/dist/tasenor-common-node/src/commands/report.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/settings.d.ts +10 -0
- package/dist/tasenor-common-node/src/commands/settings.js +64 -0
- package/dist/tasenor-common-node/src/commands/settings.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/stock.d.ts +8 -0
- package/dist/tasenor-common-node/src/commands/stock.js +73 -0
- package/dist/tasenor-common-node/src/commands/stock.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/tag.d.ts +13 -0
- package/dist/tasenor-common-node/src/commands/tag.js +89 -0
- package/dist/tasenor-common-node/src/commands/tag.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/tx.d.ts +12 -0
- package/dist/tasenor-common-node/src/commands/tx.js +81 -0
- package/dist/tasenor-common-node/src/commands/tx.js.map +1 -0
- package/dist/tasenor-common-node/src/commands/user.d.ts +12 -0
- package/dist/tasenor-common-node/src/commands/user.js +52 -0
- package/dist/tasenor-common-node/src/commands/user.js.map +1 -0
- package/dist/tasenor-common-node/src/database/BookkeeperImporter.d.ts +77 -0
- package/dist/tasenor-common-node/src/database/BookkeeperImporter.js +343 -0
- package/dist/tasenor-common-node/src/database/BookkeeperImporter.js.map +1 -0
- package/dist/tasenor-common-node/src/database/DB.d.ts +51 -0
- package/dist/tasenor-common-node/src/database/DB.js +354 -0
- package/dist/tasenor-common-node/src/database/DB.js.map +1 -0
- package/dist/tasenor-common-node/src/database/index.d.ts +7 -0
- package/dist/tasenor-common-node/src/database/index.js +8 -0
- package/dist/tasenor-common-node/src/database/index.js.map +1 -0
- package/dist/tasenor-common-node/src/doccer.d.ts +29 -0
- package/dist/tasenor-common-node/src/doccer.js +30 -0
- package/dist/tasenor-common-node/src/doccer.js.map +1 -0
- package/dist/tasenor-common-node/src/error.d.ts +30 -0
- package/dist/tasenor-common-node/src/error.js +35 -0
- package/dist/tasenor-common-node/src/error.js.map +1 -0
- package/dist/tasenor-common-node/src/export/Exporter.d.ts +69 -0
- package/dist/tasenor-common-node/src/export/Exporter.js +123 -0
- package/dist/tasenor-common-node/src/export/Exporter.js.map +1 -0
- package/dist/tasenor-common-node/src/export/TasenorExporter.d.ts +55 -0
- package/dist/tasenor-common-node/src/export/TasenorExporter.js +135 -0
- package/dist/tasenor-common-node/src/export/TasenorExporter.js.map +1 -0
- package/dist/tasenor-common-node/src/export/TilitinExporter.d.ts +71 -0
- package/dist/tasenor-common-node/src/export/TilitinExporter.js +290 -0
- package/dist/tasenor-common-node/src/export/TilitinExporter.js.map +1 -0
- package/dist/tasenor-common-node/src/export/index.d.ts +8 -0
- package/dist/tasenor-common-node/src/export/index.js +9 -0
- package/dist/tasenor-common-node/src/export/index.js.map +1 -0
- package/dist/tasenor-common-node/src/import/TextFileProcessHandler.d.ts +104 -0
- package/dist/tasenor-common-node/src/import/TextFileProcessHandler.js +354 -0
- package/dist/tasenor-common-node/src/import/TextFileProcessHandler.js.map +1 -0
- package/dist/tasenor-common-node/src/import/TransactionImportConnector.d.ts +38 -0
- package/dist/tasenor-common-node/src/import/TransactionImportConnector.js +27 -0
- package/dist/tasenor-common-node/src/import/TransactionImportConnector.js.map +1 -0
- package/dist/tasenor-common-node/src/import/TransactionImportHandler.d.ts +173 -0
- package/dist/tasenor-common-node/src/import/TransactionImportHandler.js +733 -0
- package/dist/tasenor-common-node/src/import/TransactionImportHandler.js.map +1 -0
- package/dist/tasenor-common-node/src/import/TransactionRules.d.ts +238 -0
- package/dist/tasenor-common-node/src/import/TransactionRules.js +522 -0
- package/dist/tasenor-common-node/src/import/TransactionRules.js.map +1 -0
- package/dist/tasenor-common-node/src/import/TransactionUI.d.ts +181 -0
- package/dist/tasenor-common-node/src/import/TransactionUI.js +482 -0
- package/dist/tasenor-common-node/src/import/TransactionUI.js.map +1 -0
- package/dist/tasenor-common-node/src/import/TransferAnalyzer.d.ts +324 -0
- package/dist/tasenor-common-node/src/import/TransferAnalyzer.js +1379 -0
- package/dist/tasenor-common-node/src/import/TransferAnalyzer.js.map +1 -0
- package/dist/tasenor-common-node/src/import/index.d.ts +11 -0
- package/dist/tasenor-common-node/src/import/index.js +12 -0
- package/dist/tasenor-common-node/src/import/index.js.map +1 -0
- package/dist/tasenor-common-node/src/index.d.ts +12 -0
- package/dist/tasenor-common-node/src/index.js +13 -0
- package/dist/tasenor-common-node/src/index.js.map +1 -0
- package/dist/tasenor-common-node/src/net/crypto.d.ts +33 -0
- package/dist/tasenor-common-node/src/net/crypto.js +63 -0
- package/dist/tasenor-common-node/src/net/crypto.js.map +1 -0
- package/dist/tasenor-common-node/src/net/git.d.ts +49 -0
- package/dist/tasenor-common-node/src/net/git.js +137 -0
- package/dist/tasenor-common-node/src/net/git.js.map +1 -0
- package/dist/tasenor-common-node/src/net/index.d.ts +10 -0
- package/dist/tasenor-common-node/src/net/index.js +11 -0
- package/dist/tasenor-common-node/src/net/index.js.map +1 -0
- package/dist/tasenor-common-node/src/net/middleware.d.ts +61 -0
- package/dist/tasenor-common-node/src/net/middleware.js +220 -0
- package/dist/tasenor-common-node/src/net/middleware.js.map +1 -0
- package/dist/tasenor-common-node/src/net/tokens.d.ts +50 -0
- package/dist/tasenor-common-node/src/net/tokens.js +141 -0
- package/dist/tasenor-common-node/src/net/tokens.js.map +1 -0
- package/dist/tasenor-common-node/src/net/vault.d.ts +67 -0
- package/dist/tasenor-common-node/src/net/vault.js +145 -0
- package/dist/tasenor-common-node/src/net/vault.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/BackendPlugin.d.ts +91 -0
- package/dist/tasenor-common-node/src/plugins/BackendPlugin.js +165 -0
- package/dist/tasenor-common-node/src/plugins/BackendPlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/DataPlugin.d.ts +13 -0
- package/dist/tasenor-common-node/src/plugins/DataPlugin.js +26 -0
- package/dist/tasenor-common-node/src/plugins/DataPlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/ImportPlugin.d.ts +188 -0
- package/dist/tasenor-common-node/src/plugins/ImportPlugin.js +204 -0
- package/dist/tasenor-common-node/src/plugins/ImportPlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/ReportPlugin.d.ts +132 -0
- package/dist/tasenor-common-node/src/plugins/ReportPlugin.js +393 -0
- package/dist/tasenor-common-node/src/plugins/ReportPlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/SchemePlugin.d.ts +34 -0
- package/dist/tasenor-common-node/src/plugins/SchemePlugin.js +47 -0
- package/dist/tasenor-common-node/src/plugins/SchemePlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/ServicePlugin.d.ts +80 -0
- package/dist/tasenor-common-node/src/plugins/ServicePlugin.js +168 -0
- package/dist/tasenor-common-node/src/plugins/ServicePlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/ToolPlugin.d.ts +27 -0
- package/dist/tasenor-common-node/src/plugins/ToolPlugin.js +37 -0
- package/dist/tasenor-common-node/src/plugins/ToolPlugin.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/index.d.ts +13 -0
- package/dist/tasenor-common-node/src/plugins/index.js +14 -0
- package/dist/tasenor-common-node/src/plugins/index.js.map +1 -0
- package/dist/tasenor-common-node/src/plugins/plugins.d.ts +101 -0
- package/dist/tasenor-common-node/src/plugins/plugins.js +292 -0
- package/dist/tasenor-common-node/src/plugins/plugins.js.map +1 -0
- package/dist/tasenor-common-node/src/process/Process.d.ts +108 -0
- package/dist/tasenor-common-node/src/process/Process.js +335 -0
- package/dist/tasenor-common-node/src/process/Process.js.map +1 -0
- package/dist/tasenor-common-node/src/process/ProcessConnector.d.ts +24 -0
- package/dist/tasenor-common-node/src/process/ProcessConnector.js +28 -0
- package/dist/tasenor-common-node/src/process/ProcessConnector.js.map +1 -0
- package/dist/tasenor-common-node/src/process/ProcessFile.d.ts +69 -0
- package/dist/tasenor-common-node/src/process/ProcessFile.js +145 -0
- package/dist/tasenor-common-node/src/process/ProcessFile.js.map +1 -0
- package/dist/tasenor-common-node/src/process/ProcessHandler.d.ts +60 -0
- package/dist/tasenor-common-node/src/process/ProcessHandler.js +73 -0
- package/dist/tasenor-common-node/src/process/ProcessHandler.js.map +1 -0
- package/dist/tasenor-common-node/src/process/ProcessStep.d.ts +52 -0
- package/dist/tasenor-common-node/src/process/ProcessStep.js +78 -0
- package/dist/tasenor-common-node/src/process/ProcessStep.js.map +1 -0
- package/dist/tasenor-common-node/src/process/ProcessingSystem.d.ts +60 -0
- package/dist/tasenor-common-node/src/process/ProcessingSystem.js +182 -0
- package/dist/tasenor-common-node/src/process/ProcessingSystem.js.map +1 -0
- package/dist/tasenor-common-node/src/process/index.d.ts +11 -0
- package/dist/tasenor-common-node/src/process/index.js +12 -0
- package/dist/tasenor-common-node/src/process/index.js.map +1 -0
- package/dist/tasenor-common-node/src/reports/conversions.d.ts +8 -0
- package/dist/tasenor-common-node/src/reports/conversions.js +47 -0
- package/dist/tasenor-common-node/src/reports/conversions.js.map +1 -0
- package/dist/tasenor-common-node/src/reports/index.d.ts +6 -0
- package/dist/tasenor-common-node/src/reports/index.js +7 -0
- package/dist/tasenor-common-node/src/reports/index.js.map +1 -0
- package/dist/tasenor-common-node/src/server/ISPDemoServer.d.ts +43 -0
- package/dist/tasenor-common-node/src/server/ISPDemoServer.js +112 -0
- package/dist/tasenor-common-node/src/server/ISPDemoServer.js.map +1 -0
- package/dist/tasenor-common-node/src/server/api.d.ts +15 -0
- package/dist/tasenor-common-node/src/server/api.js +27 -0
- package/dist/tasenor-common-node/src/server/api.js.map +1 -0
- package/dist/tasenor-common-node/src/server/index.d.ts +7 -0
- package/dist/tasenor-common-node/src/server/index.js +8 -0
- package/dist/tasenor-common-node/src/server/index.js.map +1 -0
- package/dist/tasenor-common-node/src/server/router.d.ts +5 -0
- package/dist/tasenor-common-node/src/server/router.js +37 -0
- package/dist/tasenor-common-node/src/server/router.js.map +1 -0
- package/dist/tasenor-common-node/src/system.d.ts +27 -0
- package/dist/tasenor-common-node/src/system.js +95 -0
- package/dist/tasenor-common-node/src/system.js.map +1 -0
- package/dist/tasenor-common-node/src/testing/ProcessingSystemMock.d.ts +21 -0
- package/dist/tasenor-common-node/src/testing/ProcessingSystemMock.js +33 -0
- package/dist/tasenor-common-node/src/testing/ProcessingSystemMock.js.map +1 -0
- package/dist/tasenor-common-node/src/testing/UnitTestImportConnector.d.ts +24 -0
- package/dist/tasenor-common-node/src/testing/UnitTestImportConnector.js +68 -0
- package/dist/tasenor-common-node/src/testing/UnitTestImportConnector.js.map +1 -0
- package/dist/tasenor-common-node/src/testing/UnitTester.d.ts +64 -0
- package/dist/tasenor-common-node/src/testing/UnitTester.js +199 -0
- package/dist/tasenor-common-node/src/testing/UnitTester.js.map +1 -0
- package/dist/tasenor-common-node/src/testing/index.d.ts +4 -0
- package/dist/tasenor-common-node/src/testing/index.js +5 -0
- package/dist/tasenor-common-node/src/testing/index.js.map +1 -0
- package/dist/tasenor-common-node/src/testing/test-handlers.d.ts +13 -0
- package/dist/tasenor-common-node/src/testing/test-handlers.js +52 -0
- package/dist/tasenor-common-node/src/testing/test-handlers.js.map +1 -0
- package/dist/tasenor-common-node/tests/TransactionRules.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/TransactionRules.spec.js +64 -0
- package/dist/tasenor-common-node/tests/TransactionRules.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-account-address.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-account-address.spec.js +80 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-account-address.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-buying-and-selling.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-buying-and-selling.spec.js +342 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-buying-and-selling.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-loans.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-loans.spec.js +174 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-loans.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-multiple-null-amounts.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-multiple-null-amounts.spec.js +175 -0
- package/dist/tasenor-common-node/tests/TransferAnalyzer-multiple-null-amounts.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/password.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/password.spec.js +8 -0
- package/dist/tasenor-common-node/tests/password.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/tokens.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/tokens.spec.js +49 -0
- package/dist/tasenor-common-node/tests/tokens.spec.js.map +1 -0
- package/dist/tasenor-common-node/tests/vault.spec.d.ts +1 -0
- package/dist/tasenor-common-node/tests/vault.spec.js +19 -0
- package/dist/tasenor-common-node/tests/vault.spec.js.map +1 -0
- package/dist/tasenor-common-plugins/src/CoinbaseImport/backend/CoinbaseHandler.d.ts +11 -0
- package/dist/tasenor-common-plugins/src/CoinbaseImport/backend/CoinbaseHandler.js +30 -0
- package/dist/tasenor-common-plugins/src/CoinbaseImport/backend/CoinbaseHandler.js.map +1 -0
- package/dist/tasenor-common-plugins/src/IncomeAndExpenses/backend/index.d.ts +5 -0
- package/dist/tasenor-common-plugins/src/IncomeAndExpenses/backend/index.js +350 -0
- package/dist/tasenor-common-plugins/src/IncomeAndExpenses/backend/index.js.map +1 -0
- package/dist/tasenor-common-plugins/src/KrakenImport/backend/KrakenHandler.d.ts +23 -0
- package/dist/tasenor-common-plugins/src/KrakenImport/backend/KrakenHandler.js +83 -0
- package/dist/tasenor-common-plugins/src/KrakenImport/backend/KrakenHandler.js.map +1 -0
- package/dist/tasenor-common-plugins/src/LynxImport/backend/LynxHandler.d.ts +28 -0
- package/dist/tasenor-common-plugins/src/LynxImport/backend/LynxHandler.js +340 -0
- package/dist/tasenor-common-plugins/src/LynxImport/backend/LynxHandler.js.map +1 -0
- package/dist/tasenor-common-plugins/src/NordeaImport/backend/NordeaHandler.d.ts +11 -0
- package/dist/tasenor-common-plugins/src/NordeaImport/backend/NordeaHandler.js +39 -0
- package/dist/tasenor-common-plugins/src/NordeaImport/backend/NordeaHandler.js.map +1 -0
- package/dist/tasenor-common-plugins/src/NordnetImport/backend/NordnetHandler.d.ts +17 -0
- package/dist/tasenor-common-plugins/src/NordnetImport/backend/NordnetHandler.js +66 -0
- package/dist/tasenor-common-plugins/src/NordnetImport/backend/NordnetHandler.js.map +1 -0
- package/dist/tasenor-common-plugins/src/TITOImport/backend/TITOHandler.d.ts +13 -0
- package/dist/tasenor-common-plugins/src/TITOImport/backend/TITOHandler.js +241 -0
- package/dist/tasenor-common-plugins/src/TITOImport/backend/TITOHandler.js.map +1 -0
- package/jest.config.js +1 -0
- package/package.json +62 -0
- package/src/cli.ts +267 -0
- package/src/commands/account.ts +69 -0
- package/src/commands/balance.ts +131 -0
- package/src/commands/db.ts +84 -0
- package/src/commands/entry.ts +117 -0
- package/src/commands/import.ts +160 -0
- package/src/commands/importer.ts +84 -0
- package/src/commands/index.ts +534 -0
- package/src/commands/period.ts +59 -0
- package/src/commands/plugin.ts +95 -0
- package/src/commands/report.ts +113 -0
- package/src/commands/settings.ts +75 -0
- package/src/commands/stock.ts +80 -0
- package/src/commands/tag.ts +102 -0
- package/src/commands/tx.ts +93 -0
- package/src/commands/user.ts +65 -0
- package/src/database/BookkeeperImporter.ts +358 -0
- package/src/database/DB.ts +396 -0
- package/src/database/index.ts +7 -0
- package/src/doccer.ts +29 -0
- package/src/error.ts +32 -0
- package/src/export/Exporter.ts +136 -0
- package/src/export/TasenorExporter.ts +144 -0
- package/src/export/TilitinExporter.ts +302 -0
- package/src/export/index.ts +8 -0
- package/src/import/TextFileProcessHandler.ts +384 -0
- package/src/import/TransactionImportConnector.ts +65 -0
- package/src/import/TransactionImportHandler.ts +819 -0
- package/src/import/TransactionRules.ts +570 -0
- package/src/import/TransactionUI.ts +520 -0
- package/src/import/TransferAnalyzer.ts +1450 -0
- package/src/import/index.ts +11 -0
- package/src/index.ts +12 -0
- package/src/net/crypto.ts +69 -0
- package/src/net/git.ts +151 -0
- package/src/net/index.ts +10 -0
- package/src/net/middleware.ts +261 -0
- package/src/net/tokens.ts +140 -0
- package/src/net/vault.ts +161 -0
- package/src/plugins/BackendPlugin.ts +188 -0
- package/src/plugins/DataPlugin.ts +29 -0
- package/src/plugins/ImportPlugin.ts +211 -0
- package/src/plugins/ReportPlugin.ts +443 -0
- package/src/plugins/SchemePlugin.ts +56 -0
- package/src/plugins/ServicePlugin.ts +188 -0
- package/src/plugins/ToolPlugin.ts +44 -0
- package/src/plugins/index.ts +13 -0
- package/src/plugins/plugins.ts +345 -0
- package/src/process/Process.ts +368 -0
- package/src/process/ProcessConnector.ts +45 -0
- package/src/process/ProcessFile.ts +169 -0
- package/src/process/ProcessHandler.ts +94 -0
- package/src/process/ProcessStep.ts +100 -0
- package/src/process/ProcessingSystem.ts +202 -0
- package/src/process/index.ts +11 -0
- package/src/reports/conversions.ts +52 -0
- package/src/reports/index.ts +6 -0
- package/src/server/ISPDemoServer.ts +122 -0
- package/src/server/api.ts +37 -0
- package/src/server/index.ts +7 -0
- package/src/server/router.ts +60 -0
- package/src/system.ts +96 -0
- package/src/testing/ProcessingSystemMock.ts +45 -0
- package/src/testing/UnitTestImportConnector.ts +86 -0
- package/src/testing/UnitTester.ts +231 -0
- package/src/testing/index.ts +4 -0
- package/src/testing/test-handlers.ts +55 -0
- package/tests/TransactionRules.spec.ts +73 -0
- package/tests/TransferAnalyzer-account-address.spec.ts +87 -0
- package/tests/TransferAnalyzer-buying-and-selling.spec.ts +354 -0
- package/tests/TransferAnalyzer-loans.spec.ts +197 -0
- package/tests/TransferAnalyzer-multiple-null-amounts.spec.ts +181 -0
- package/tests/password.spec.ts +8 -0
- package/tests/tokens.spec.ts +52 -0
- package/tests/vault.spec.ts +20 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Process } from './Process'
|
|
2
|
+
import { DatabaseError } from '../error'
|
|
3
|
+
import { KnexDatabase } from '../database'
|
|
4
|
+
import { ID, Directions, ImportAction, ImportState } from '@dataplug/tasenor-common'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A basic information of the processing step.
|
|
8
|
+
*/
|
|
9
|
+
export interface ProcessStepData {
|
|
10
|
+
processId?: ID
|
|
11
|
+
number: number
|
|
12
|
+
state: ImportState
|
|
13
|
+
handler: string
|
|
14
|
+
action?: ImportAction
|
|
15
|
+
directions?: Directions
|
|
16
|
+
started?: Date
|
|
17
|
+
finished?: Date
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Data of the one step in the process including possible directions and action taken to the next step, if any.
|
|
22
|
+
*/
|
|
23
|
+
export class ProcessStep {
|
|
24
|
+
|
|
25
|
+
process: Process
|
|
26
|
+
|
|
27
|
+
id: ID
|
|
28
|
+
processId: ID
|
|
29
|
+
number: number
|
|
30
|
+
state: ImportState
|
|
31
|
+
handler: string
|
|
32
|
+
started: Date | undefined
|
|
33
|
+
finished: Date | undefined
|
|
34
|
+
directions?: Directions
|
|
35
|
+
action?: ImportAction | undefined
|
|
36
|
+
|
|
37
|
+
constructor(obj: ProcessStepData) {
|
|
38
|
+
this.processId = obj.processId || null
|
|
39
|
+
this.number = obj.number
|
|
40
|
+
this.state = obj.state
|
|
41
|
+
this.handler = obj.handler
|
|
42
|
+
this.directions = obj.directions ? new Directions(obj.directions) : undefined
|
|
43
|
+
this.action = obj.action
|
|
44
|
+
this.started = obj.started
|
|
45
|
+
this.finished = obj.finished
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
toString(): string {
|
|
49
|
+
return `ProcessStep ${this.number} of Process #${this.processId}`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get a reference to the database.
|
|
54
|
+
*/
|
|
55
|
+
get db(): KnexDatabase {
|
|
56
|
+
return this.process.db
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Save the process info to the database.
|
|
61
|
+
*/
|
|
62
|
+
async save(): Promise<ID> {
|
|
63
|
+
if (this.id) {
|
|
64
|
+
await this.db('process_steps').update(this.toJSON()).where({ id: this.id })
|
|
65
|
+
return this.id
|
|
66
|
+
} else {
|
|
67
|
+
this.started = new Date()
|
|
68
|
+
this.id = (await this.db('process_steps').insert(this.toJSON()).returning('id'))[0].id
|
|
69
|
+
if (this.id) return this.id
|
|
70
|
+
throw new DatabaseError(`Saving process ${JSON.stringify(this.toJSON)} failed.`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get the loaded process information as JSON object.
|
|
76
|
+
* @returns
|
|
77
|
+
*/
|
|
78
|
+
toJSON(): ProcessStepData {
|
|
79
|
+
return {
|
|
80
|
+
processId: this.processId,
|
|
81
|
+
number: this.number,
|
|
82
|
+
state: this.state,
|
|
83
|
+
directions: this.directions,
|
|
84
|
+
handler: this.handler,
|
|
85
|
+
action: this.action,
|
|
86
|
+
started: this.started,
|
|
87
|
+
finished: this.finished
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Set directions and update database.
|
|
93
|
+
* @param db
|
|
94
|
+
* @param directions
|
|
95
|
+
*/
|
|
96
|
+
async setDirections(db: KnexDatabase, directions: Directions): Promise<void> {
|
|
97
|
+
this.directions = directions
|
|
98
|
+
await db('process_steps').update({ directions: directions.toJSON() }).where({ id: this.id })
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { Process } from './Process'
|
|
2
|
+
import { ProcessFile, ProcessFileData } from './ProcessFile'
|
|
3
|
+
import { ProcessStep } from './ProcessStep'
|
|
4
|
+
import { ProcessHandler, ProcessHandlerMap } from './ProcessHandler'
|
|
5
|
+
import { ProcessConnector } from './ProcessConnector'
|
|
6
|
+
import { ProcessName, ProcessConfig, ID } from '@dataplug/tasenor-common'
|
|
7
|
+
import { InvalidArgument } from '../error'
|
|
8
|
+
import { KnexDatabase } from '../database'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* An instance of the full processing system.
|
|
12
|
+
*/
|
|
13
|
+
export class ProcessingSystem {
|
|
14
|
+
|
|
15
|
+
db: KnexDatabase
|
|
16
|
+
handlers: ProcessHandlerMap = {}
|
|
17
|
+
connector: ProcessConnector
|
|
18
|
+
logger: {
|
|
19
|
+
info: (...msg) => void
|
|
20
|
+
error: (...msg) => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the system and set the database instance for storing process data.
|
|
25
|
+
* @param db
|
|
26
|
+
*/
|
|
27
|
+
constructor(db: KnexDatabase, connector: ProcessConnector) {
|
|
28
|
+
this.db = db
|
|
29
|
+
this.logger = {
|
|
30
|
+
info: (...msg) => console.log(new Date(), ...msg),
|
|
31
|
+
error: (...msg) => console.error(new Date(), ...msg)
|
|
32
|
+
}
|
|
33
|
+
this.connector = connector
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the translation from the connector.
|
|
38
|
+
* @param language
|
|
39
|
+
* @param text
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
async getTranslation(text: string, language: string): Promise<string> {
|
|
43
|
+
return this.connector.getTranslation(text, language)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Register new handler class for processing.
|
|
48
|
+
* @param handler
|
|
49
|
+
*/
|
|
50
|
+
register(handler: ProcessHandler): void {
|
|
51
|
+
if (!handler) {
|
|
52
|
+
throw new InvalidArgument('A handler was undefined.')
|
|
53
|
+
}
|
|
54
|
+
if (!handler.name) {
|
|
55
|
+
throw new InvalidArgument('A handler without name cannot be registered.')
|
|
56
|
+
}
|
|
57
|
+
if (handler.name in this.handlers) {
|
|
58
|
+
throw new InvalidArgument(`The handler '${handler.name}' is already defined.`)
|
|
59
|
+
}
|
|
60
|
+
if (handler.name.length > 32) {
|
|
61
|
+
throw new InvalidArgument(`The handler name '${handler.name}' is too long.`)
|
|
62
|
+
}
|
|
63
|
+
handler.system = this
|
|
64
|
+
this.handlers[handler.name] = handler
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Initialize new process and save it to the database.
|
|
69
|
+
* @param type
|
|
70
|
+
* @param name
|
|
71
|
+
* @param file
|
|
72
|
+
* @returns New process that is already in crashed state, if no handler
|
|
73
|
+
*/
|
|
74
|
+
async createProcess(name: ProcessName, files: ProcessFileData[], config: ProcessConfig): Promise<Process> {
|
|
75
|
+
// Set up the process.
|
|
76
|
+
const process = new Process(this, name, config)
|
|
77
|
+
await process.save()
|
|
78
|
+
|
|
79
|
+
// Check if we have files.
|
|
80
|
+
if (files.length < 1) {
|
|
81
|
+
await process.crashed(new InvalidArgument('No files given to create a process.'))
|
|
82
|
+
return process
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Save the first file and attach it to the process.
|
|
86
|
+
const file = files[0]
|
|
87
|
+
const processFile = new ProcessFile(file)
|
|
88
|
+
process.addFile(processFile)
|
|
89
|
+
await processFile.save(this.db)
|
|
90
|
+
|
|
91
|
+
// Find the handler.
|
|
92
|
+
let selectedHandler: ProcessHandler | null = null
|
|
93
|
+
for (const handler of Object.values(this.handlers)) {
|
|
94
|
+
try {
|
|
95
|
+
if (handler.canHandle(processFile)) {
|
|
96
|
+
selectedHandler = handler
|
|
97
|
+
break
|
|
98
|
+
}
|
|
99
|
+
} catch (err) {
|
|
100
|
+
await process.crashed(err)
|
|
101
|
+
return process
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!selectedHandler) {
|
|
105
|
+
await process.crashed(new InvalidArgument(`No handler found for the file ${file.name} of type ${file.type}.`))
|
|
106
|
+
return process
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Check if the handler accepts the rest of the files.
|
|
110
|
+
for (let i = 1; i < files.length; i++) {
|
|
111
|
+
const processFile = new ProcessFile(files[i])
|
|
112
|
+
// await processFile.save(this.db)
|
|
113
|
+
if (!selectedHandler.canAppend(processFile)) {
|
|
114
|
+
await process.crashed(new InvalidArgument(`The file ${files[i].name} of type ${files[i].type} cannot be appended to handler.`))
|
|
115
|
+
return process
|
|
116
|
+
}
|
|
117
|
+
process.addFile(processFile)
|
|
118
|
+
await processFile.save(this.db)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Create initial step using the handler.
|
|
122
|
+
let state
|
|
123
|
+
try {
|
|
124
|
+
state = selectedHandler.startingState(process.files)
|
|
125
|
+
} catch (err) {
|
|
126
|
+
await process.crashed(err)
|
|
127
|
+
return process
|
|
128
|
+
}
|
|
129
|
+
const step = new ProcessStep({
|
|
130
|
+
number: 0,
|
|
131
|
+
handler: selectedHandler.name,
|
|
132
|
+
state
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
process.addStep(step)
|
|
136
|
+
await step.save()
|
|
137
|
+
|
|
138
|
+
process.currentStep = 0
|
|
139
|
+
await process.save()
|
|
140
|
+
this.logger.info(`Created process ${process}.`)
|
|
141
|
+
|
|
142
|
+
// Find directions forward from the initial state.
|
|
143
|
+
await this.checkFinishAndFindDirections(selectedHandler, step)
|
|
144
|
+
|
|
145
|
+
return process
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Check if we are in the finished state and if not, find the directions forward.
|
|
150
|
+
*/
|
|
151
|
+
async checkFinishAndFindDirections(handler: ProcessHandler, step: ProcessStep): Promise<void> {
|
|
152
|
+
let result
|
|
153
|
+
try {
|
|
154
|
+
result = handler.checkCompletion(step.state)
|
|
155
|
+
} catch (err) {
|
|
156
|
+
return step.process.crashed(err)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (result === undefined) {
|
|
160
|
+
let directions
|
|
161
|
+
try {
|
|
162
|
+
directions = await handler.getDirections(step.state, step.process.config)
|
|
163
|
+
} catch (err) {
|
|
164
|
+
return step.process.crashed(err)
|
|
165
|
+
}
|
|
166
|
+
await step.setDirections(this.db, directions)
|
|
167
|
+
} else {
|
|
168
|
+
// Process is finished.
|
|
169
|
+
step.directions = undefined
|
|
170
|
+
step.action = undefined
|
|
171
|
+
step.finished = new Date()
|
|
172
|
+
await step.save()
|
|
173
|
+
step.process.complete = true
|
|
174
|
+
step.process.successful = result
|
|
175
|
+
await step.process.save()
|
|
176
|
+
}
|
|
177
|
+
await step.process.updateStatus()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get the named handler or throw an error if not registered.
|
|
182
|
+
* @param name
|
|
183
|
+
* @returns
|
|
184
|
+
*/
|
|
185
|
+
getHandler(name: string): ProcessHandler {
|
|
186
|
+
if (!(name in this.handlers)) {
|
|
187
|
+
throw new InvalidArgument(`There is no handler for '${name}'.`)
|
|
188
|
+
}
|
|
189
|
+
return this.handlers[name]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Load the process data from the disk.
|
|
194
|
+
* @param id
|
|
195
|
+
* @returns
|
|
196
|
+
*/
|
|
197
|
+
async loadProcess(id: ID): Promise<Process> {
|
|
198
|
+
const process = new Process(this, null)
|
|
199
|
+
await process.load(id)
|
|
200
|
+
return process
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implementation for process handling.
|
|
3
|
+
*
|
|
4
|
+
* @module tasenor-common-node/src/process
|
|
5
|
+
*/
|
|
6
|
+
export * from './Process'
|
|
7
|
+
export * from './ProcessConnector'
|
|
8
|
+
export * from './ProcessFile'
|
|
9
|
+
export * from './ProcessingSystem'
|
|
10
|
+
export * from './ProcessStep'
|
|
11
|
+
export * from './ProcessHandler'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ReportQueryParams } from '@dataplug/tasenor-common'
|
|
2
|
+
import json2csv from 'json2csv'
|
|
3
|
+
import { sprintf } from 'sprintf-js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert report to CSV format.
|
|
7
|
+
* @param {Object} report
|
|
8
|
+
* @param {Object} options
|
|
9
|
+
* @param {String} options.lang Localize number using this language.
|
|
10
|
+
*/
|
|
11
|
+
export function data2csv(report, options: ReportQueryParams) {
|
|
12
|
+
const csv: Record<string, string>[] = []
|
|
13
|
+
|
|
14
|
+
const render = {
|
|
15
|
+
id: (column, entry) => entry.id,
|
|
16
|
+
name: (column, entry) => `${entry.isAccount ? entry.number + ' ' : ''}${entry.name}`,
|
|
17
|
+
text: (column, entry) => entry[column.name],
|
|
18
|
+
numeric: (column, entry) => (entry.amounts &&
|
|
19
|
+
!entry.hideTotal &&
|
|
20
|
+
entry.amounts[column.name] !== '' &&
|
|
21
|
+
!isNaN(entry.amounts[column.name]) &&
|
|
22
|
+
entry.amounts[column.name] !== undefined)
|
|
23
|
+
? (entry.amounts[column.name] === null ? '—' : sprintf('%.2f', entry.amounts[column.name] / 100))
|
|
24
|
+
: ''
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { data, columns } = report
|
|
28
|
+
let line: Record<string, string> = {}
|
|
29
|
+
if (!options.dropTitle) {
|
|
30
|
+
columns.forEach((column) => (line[column.name] = column.title))
|
|
31
|
+
csv.push(line)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
data.forEach((entry) => {
|
|
35
|
+
if (entry.paragraphBreak) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
line = {}
|
|
39
|
+
columns.forEach((column) => {
|
|
40
|
+
if (entry.pageBreak || entry.paragraphBreak) {
|
|
41
|
+
line[column.name] = ''
|
|
42
|
+
} else {
|
|
43
|
+
line[column.name] = render[column.type](column, entry)
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
csv.push(line)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const fields = columns.map((c) => c.name)
|
|
50
|
+
|
|
51
|
+
return json2csv.parse(csv, { fields, header: false })
|
|
52
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import express from 'express'
|
|
3
|
+
import { Server } from 'http'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
import Knex from 'knex'
|
|
6
|
+
import cors from 'cors'
|
|
7
|
+
import { router } from './router'
|
|
8
|
+
import { ID } from '@dataplug/tasenor-common'
|
|
9
|
+
import { ProcessHandler, ProcessConnector, defaultConnector, ProcessingSystem } from '../process'
|
|
10
|
+
import { KnexDatabase } from '../database'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Simple demo server for one or more handler.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```
|
|
17
|
+
* const handler1 = new MyCustomHandler('Custom 1')
|
|
18
|
+
* const handler2 = new MyCustomHandler('Custom 2')
|
|
19
|
+
* const server = new ISPDemoServer(PORT, DATABASE_URL, [handler1, handler2])
|
|
20
|
+
* server.start()
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class ISPDemoServer {
|
|
24
|
+
private app = express()
|
|
25
|
+
private server: Server
|
|
26
|
+
private port: number
|
|
27
|
+
private db: KnexDatabase
|
|
28
|
+
private handlers: ProcessHandler[]
|
|
29
|
+
private connector: ProcessConnector
|
|
30
|
+
private configDefaults: Record<string, unknown>
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Prepare settings.
|
|
34
|
+
*
|
|
35
|
+
* @param port
|
|
36
|
+
* @param databaseUrl
|
|
37
|
+
* @param handlers
|
|
38
|
+
* @param connector
|
|
39
|
+
*/
|
|
40
|
+
constructor(port: number, databaseUrl: string, handlers: ProcessHandler[], connector: ProcessConnector|null = null, configDefaults: Record<string, unknown> = {}) {
|
|
41
|
+
this.port = port
|
|
42
|
+
this.configDefaults = configDefaults
|
|
43
|
+
let migrationsPath = path.normalize(path.join(__dirname, '/migrations/01_init.js'))
|
|
44
|
+
if (!fs.existsSync(migrationsPath)) {
|
|
45
|
+
migrationsPath = path.normalize(path.join(__dirname, '../../dist/migrations/01_init.js'))
|
|
46
|
+
}
|
|
47
|
+
if (!fs.existsSync(migrationsPath)) {
|
|
48
|
+
migrationsPath = path.normalize(path.join(__dirname, '../../../dist/migrations/01_init.js'))
|
|
49
|
+
}
|
|
50
|
+
if (!fs.existsSync(migrationsPath)) {
|
|
51
|
+
console.log(__dirname)
|
|
52
|
+
throw new Error(`Cannot find migrations file '${migrationsPath}'.`)
|
|
53
|
+
}
|
|
54
|
+
this.db = Knex({
|
|
55
|
+
client: 'pg',
|
|
56
|
+
connection: databaseUrl,
|
|
57
|
+
migrations: {
|
|
58
|
+
directory: path.dirname(migrationsPath)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
this.handlers = handlers
|
|
62
|
+
if (connector) {
|
|
63
|
+
this.connector = connector
|
|
64
|
+
} else {
|
|
65
|
+
this.connector = defaultConnector
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Launch the demo server.
|
|
71
|
+
*
|
|
72
|
+
* @param reset If set, reset the database on boot.
|
|
73
|
+
*/
|
|
74
|
+
public start = async (reset = false): Promise<void> => {
|
|
75
|
+
|
|
76
|
+
if (reset) {
|
|
77
|
+
await this.db.migrate.rollback()
|
|
78
|
+
}
|
|
79
|
+
await this.db.migrate.latest()
|
|
80
|
+
|
|
81
|
+
const systemCreator = () => {
|
|
82
|
+
const system = new ProcessingSystem(this.db, this.connector)
|
|
83
|
+
this.handlers.forEach(handler => system.register(handler))
|
|
84
|
+
return system
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.app.use((req, res, next) => { res.locals.server = this; next() })
|
|
88
|
+
this.app.use((req, res, next) => { console.log(new Date(), req.method, req.url); next() })
|
|
89
|
+
this.app.use(cors())
|
|
90
|
+
this.app.use(express.json({ limit: '1024MB' }))
|
|
91
|
+
this.app.use('/api/isp', router(this.db, systemCreator))
|
|
92
|
+
|
|
93
|
+
this.server = this.app.listen(this.port, () => {
|
|
94
|
+
console.log(new Date(), `Server started on port ${this.port}.`)
|
|
95
|
+
this.connector.initialize(this)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
this.server.on('error', (msg) => {
|
|
99
|
+
console.error(new Date(), msg)
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Exit the server. If an error is given, raise also that error.
|
|
105
|
+
* @param err
|
|
106
|
+
*/
|
|
107
|
+
public stop = async (err: Error | undefined = undefined): Promise<void> => {
|
|
108
|
+
console.log(new Date(), 'Stopping the server.')
|
|
109
|
+
await this.server.close(() => {
|
|
110
|
+
if (err) {
|
|
111
|
+
throw err
|
|
112
|
+
} else {
|
|
113
|
+
process.exit()
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async lastProcessID(): Promise<ID> {
|
|
119
|
+
const ids = await this.db('processes').max('id').first()
|
|
120
|
+
return ids ? ids.max : null
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ProcessModelData, ID, ProcessModelDetailedData, ProcessStepModelData } from '@dataplug/tasenor-common'
|
|
2
|
+
import { KnexDatabase } from '../database'
|
|
3
|
+
|
|
4
|
+
export type ProcessApi = {
|
|
5
|
+
process: {
|
|
6
|
+
getAll: () => Promise<ProcessModelData[]>,
|
|
7
|
+
get: (id: ID) => Promise<ProcessModelDetailedData>
|
|
8
|
+
getStep: (id: ID, step: number) => Promise<ProcessStepModelData>
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Data query API for processes.
|
|
14
|
+
* @param db
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export default function(db: KnexDatabase): ProcessApi {
|
|
18
|
+
return {
|
|
19
|
+
process: {
|
|
20
|
+
getAll: async (): Promise<ProcessModelData[]> => {
|
|
21
|
+
return db('processes').select('*').orderBy('created', 'desc')
|
|
22
|
+
},
|
|
23
|
+
get: async (id: ID): Promise<ProcessModelDetailedData> => {
|
|
24
|
+
const data = await db('processes').select('*').where({ id }).first()
|
|
25
|
+
if (data) {
|
|
26
|
+
const steps = await db('process_steps').select('id', 'action', 'directions', 'number', 'started', 'finished').where({ processId: id }).orderBy('number')
|
|
27
|
+
data.steps = steps || []
|
|
28
|
+
}
|
|
29
|
+
return data
|
|
30
|
+
},
|
|
31
|
+
getStep: async (id: ID, number: number): Promise<ProcessStepModelData> => {
|
|
32
|
+
const data = await db('process_steps').select('*').where({ processId: id, number }).first()
|
|
33
|
+
return data
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import express, { Request, Router } from 'express'
|
|
2
|
+
import { KnexDatabase } from '../database'
|
|
3
|
+
import { ProcessingSystem } from '../process'
|
|
4
|
+
import apiCreator from './api'
|
|
5
|
+
|
|
6
|
+
export type ProcessingConfigurator = (req: Request) => ProcessingSystem
|
|
7
|
+
export function router(db: KnexDatabase, configurator: ProcessingConfigurator): Router {
|
|
8
|
+
|
|
9
|
+
const router = express.Router()
|
|
10
|
+
const api = apiCreator(db)
|
|
11
|
+
|
|
12
|
+
router.get('/',
|
|
13
|
+
async (req, res) => {
|
|
14
|
+
return res.send(await api.process.getAll())
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
router.get('/:id',
|
|
19
|
+
async (req, res) => {
|
|
20
|
+
return res.send(await api.process.get(parseInt(req.params.id)))
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
router.post('/',
|
|
25
|
+
async (req, res) => {
|
|
26
|
+
const system = configurator(req)
|
|
27
|
+
const { files, config } = req.body
|
|
28
|
+
const names = files.map(f => f.name)
|
|
29
|
+
const process = await system.createProcess(
|
|
30
|
+
`Uploading files ${names.join(', ')}`,
|
|
31
|
+
files,
|
|
32
|
+
{ ...res.locals.server.configDefaults, ...config }
|
|
33
|
+
)
|
|
34
|
+
if (process.canRun()) {
|
|
35
|
+
await process.run()
|
|
36
|
+
}
|
|
37
|
+
return res.send(await api.process.get(process.id))
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
router.post('/:id',
|
|
41
|
+
async (req, res) => {
|
|
42
|
+
const system = configurator(req)
|
|
43
|
+
const { id } = req.params
|
|
44
|
+
const process = await system.loadProcess(parseInt(id))
|
|
45
|
+
await process.input(req.body)
|
|
46
|
+
if (process.canRun()) {
|
|
47
|
+
await process.run()
|
|
48
|
+
}
|
|
49
|
+
res.sendStatus(204)
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
router.get('/:id/step/:number',
|
|
54
|
+
async (req, res) => {
|
|
55
|
+
return res.send(await api.process.getStep(parseInt(req.params.id), parseInt(req.params.number)))
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
return router
|
|
60
|
+
}
|
package/src/system.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server operating system related functions.
|
|
3
|
+
*
|
|
4
|
+
* @module tasenor-common-node/src/system
|
|
5
|
+
*/
|
|
6
|
+
import { exec, spawn } from 'child_process'
|
|
7
|
+
import { log, error, note } from '@dataplug/tasenor-common'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Helper to execute system command as a promise.
|
|
11
|
+
* @param command A command.
|
|
12
|
+
* @param quiet If set, do not output.
|
|
13
|
+
* @returns Srandard output if successfully executed.
|
|
14
|
+
*/
|
|
15
|
+
export async function system(command: string, quiet = false): Promise<string> {
|
|
16
|
+
if (!quiet) {
|
|
17
|
+
log(`Running system command: ${command}`)
|
|
18
|
+
}
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
exec(command, { maxBuffer: 1024 * 1024 * 500 }, (err, stdout, stderr) => {
|
|
21
|
+
if (err) {
|
|
22
|
+
if (!quiet) error(err)
|
|
23
|
+
return reject(err)
|
|
24
|
+
}
|
|
25
|
+
if (stderr && !quiet) {
|
|
26
|
+
note(`${stderr}`)
|
|
27
|
+
}
|
|
28
|
+
if (stdout && !quiet) {
|
|
29
|
+
log(`${stdout}`)
|
|
30
|
+
}
|
|
31
|
+
resolve(stdout)
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A system call showing real time output of stdout.
|
|
38
|
+
* @param command
|
|
39
|
+
* @param quiet
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
export async function systemPiped(command: string, quiet = false, ignoreError = false): Promise<string | null> {
|
|
43
|
+
if (!quiet) {
|
|
44
|
+
log(`Running system command: ${command}`)
|
|
45
|
+
}
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
let out = ''
|
|
48
|
+
const proc = spawn(command, { shell: true })
|
|
49
|
+
proc.stdout.on('data', (data) => {
|
|
50
|
+
out += data
|
|
51
|
+
if (!quiet) process.stdout.write(data)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
proc.stderr.on('data', (data) => {
|
|
55
|
+
if (!quiet) process.stderr.write(data)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
proc.on('close', (code) => {
|
|
59
|
+
if (code) {
|
|
60
|
+
if (ignoreError) {
|
|
61
|
+
resolve(null)
|
|
62
|
+
} else {
|
|
63
|
+
reject(new Error(`Call '${command}' failed with code ${code}.`))
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
resolve(out)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if the current environment is not development environment.
|
|
74
|
+
*/
|
|
75
|
+
export function isProduction(): boolean {
|
|
76
|
+
return !isDevelopment()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check and return the operating environment.
|
|
81
|
+
* @returns
|
|
82
|
+
*/
|
|
83
|
+
export function nodeEnv() {
|
|
84
|
+
const env = process.env.NODE_ENV || 'production'
|
|
85
|
+
if (!['development', 'staging', 'production'].includes(env)) {
|
|
86
|
+
throw new Error(`Invalid NODE_ENV ${env}.`)
|
|
87
|
+
}
|
|
88
|
+
return env
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Check if the current environment is development environment.
|
|
93
|
+
*/
|
|
94
|
+
export function isDevelopment(): boolean {
|
|
95
|
+
return nodeEnv() === 'development'
|
|
96
|
+
}
|