@tasenor/common-node 1.9.32 → 1.9.34
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/dist/migrations/01_init.js +60 -0
- package/dist/src/cli.d.ts +81 -0
- package/dist/src/cli.js +242 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/account.d.ts +12 -0
- package/dist/src/commands/account.js +58 -0
- package/dist/src/commands/account.js.map +1 -0
- package/dist/src/commands/balance.d.ts +11 -0
- package/dist/src/commands/balance.js +117 -0
- package/dist/src/commands/balance.js.map +1 -0
- package/dist/src/commands/db.d.ts +14 -0
- package/dist/src/commands/db.js +69 -0
- package/dist/src/commands/db.js.map +1 -0
- package/dist/src/commands/entry.d.ts +13 -0
- package/dist/src/commands/entry.js +106 -0
- package/dist/src/commands/entry.js.map +1 -0
- package/dist/src/commands/import.d.ts +17 -0
- package/dist/src/commands/import.js +140 -0
- package/dist/src/commands/import.js.map +1 -0
- package/dist/src/commands/importer.d.ts +13 -0
- package/dist/src/commands/importer.js +71 -0
- package/dist/src/commands/importer.js.map +1 -0
- package/dist/src/commands/index.d.ts +191 -0
- package/dist/src/commands/index.js +482 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/period.d.ts +12 -0
- package/dist/src/commands/period.js +48 -0
- package/dist/src/commands/period.js.map +1 -0
- package/dist/src/commands/plugin.d.ts +15 -0
- package/dist/src/commands/plugin.js +78 -0
- package/dist/src/commands/plugin.js.map +1 -0
- package/dist/src/commands/report.d.ts +11 -0
- package/dist/src/commands/report.js +96 -0
- package/dist/src/commands/report.js.map +1 -0
- package/dist/src/commands/settings.d.ts +10 -0
- package/dist/src/commands/settings.js +64 -0
- package/dist/src/commands/settings.js.map +1 -0
- package/dist/src/commands/stock.d.ts +8 -0
- package/dist/src/commands/stock.js +73 -0
- package/dist/src/commands/stock.js.map +1 -0
- package/dist/src/commands/tag.d.ts +13 -0
- package/dist/src/commands/tag.js +89 -0
- package/dist/src/commands/tag.js.map +1 -0
- package/dist/src/commands/tx.d.ts +12 -0
- package/dist/src/commands/tx.js +81 -0
- package/dist/src/commands/tx.js.map +1 -0
- package/dist/src/commands/user.d.ts +12 -0
- package/dist/src/commands/user.js +52 -0
- package/dist/src/commands/user.js.map +1 -0
- package/dist/src/database/BookkeeperImporter.d.ts +77 -0
- package/dist/src/database/BookkeeperImporter.js +343 -0
- package/dist/src/database/BookkeeperImporter.js.map +1 -0
- package/dist/src/database/DB.d.ts +51 -0
- package/dist/src/database/DB.js +354 -0
- package/dist/src/database/DB.js.map +1 -0
- package/dist/src/database/index.d.ts +7 -0
- package/dist/src/database/index.js +8 -0
- package/dist/src/database/index.js.map +1 -0
- package/dist/src/doccer.d.ts +29 -0
- package/dist/src/doccer.js +30 -0
- package/dist/src/doccer.js.map +1 -0
- package/dist/src/error.d.ts +30 -0
- package/dist/src/error.js +35 -0
- package/dist/src/error.js.map +1 -0
- package/dist/src/export/Exporter.d.ts +69 -0
- package/dist/src/export/Exporter.js +123 -0
- package/dist/src/export/Exporter.js.map +1 -0
- package/dist/src/export/TasenorExporter.d.ts +55 -0
- package/dist/src/export/TasenorExporter.js +135 -0
- package/dist/src/export/TasenorExporter.js.map +1 -0
- package/dist/src/export/TilitinExporter.d.ts +71 -0
- package/dist/src/export/TilitinExporter.js +290 -0
- package/dist/src/export/TilitinExporter.js.map +1 -0
- package/dist/src/export/index.d.ts +8 -0
- package/dist/src/export/index.js +9 -0
- package/dist/src/export/index.js.map +1 -0
- package/dist/src/import/TextFileProcessHandler.d.ts +104 -0
- package/dist/src/import/TextFileProcessHandler.js +354 -0
- package/dist/src/import/TextFileProcessHandler.js.map +1 -0
- package/dist/src/import/TransactionImportConnector.d.ts +38 -0
- package/dist/src/import/TransactionImportConnector.js +27 -0
- package/dist/src/import/TransactionImportConnector.js.map +1 -0
- package/dist/src/import/TransactionImportHandler.d.ts +174 -0
- package/dist/src/import/TransactionImportHandler.js +736 -0
- package/dist/src/import/TransactionImportHandler.js.map +1 -0
- package/dist/src/import/TransactionRules.d.ts +238 -0
- package/dist/src/import/TransactionRules.js +522 -0
- package/dist/src/import/TransactionRules.js.map +1 -0
- package/dist/src/import/TransactionUI.d.ts +181 -0
- package/dist/src/import/TransactionUI.js +482 -0
- package/dist/src/import/TransactionUI.js.map +1 -0
- package/dist/src/import/TransferAnalyzer.d.ts +324 -0
- package/dist/src/import/TransferAnalyzer.js +1379 -0
- package/dist/src/import/TransferAnalyzer.js.map +1 -0
- package/dist/src/import/index.d.ts +11 -0
- package/dist/src/import/index.js +12 -0
- package/dist/src/import/index.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/net/crypto.d.ts +33 -0
- package/dist/src/net/crypto.js +63 -0
- package/dist/src/net/crypto.js.map +1 -0
- package/dist/src/net/git.d.ts +49 -0
- package/dist/src/net/git.js +137 -0
- package/dist/src/net/git.js.map +1 -0
- package/dist/src/net/index.d.ts +10 -0
- package/dist/src/net/index.js +11 -0
- package/dist/src/net/index.js.map +1 -0
- package/dist/src/net/middleware.d.ts +61 -0
- package/dist/src/net/middleware.js +220 -0
- package/dist/src/net/middleware.js.map +1 -0
- package/dist/src/net/tokens.d.ts +50 -0
- package/dist/src/net/tokens.js +141 -0
- package/dist/src/net/tokens.js.map +1 -0
- package/dist/src/net/vault.d.ts +67 -0
- package/dist/src/net/vault.js +145 -0
- package/dist/src/net/vault.js.map +1 -0
- package/dist/src/plugins/BackendPlugin.d.ts +91 -0
- package/dist/src/plugins/BackendPlugin.js +165 -0
- package/dist/src/plugins/BackendPlugin.js.map +1 -0
- package/dist/src/plugins/DataPlugin.d.ts +13 -0
- package/dist/src/plugins/DataPlugin.js +26 -0
- package/dist/src/plugins/DataPlugin.js.map +1 -0
- package/dist/src/plugins/ImportPlugin.d.ts +188 -0
- package/dist/src/plugins/ImportPlugin.js +204 -0
- package/dist/src/plugins/ImportPlugin.js.map +1 -0
- package/dist/src/plugins/ReportPlugin.d.ts +132 -0
- package/dist/src/plugins/ReportPlugin.js +393 -0
- package/dist/src/plugins/ReportPlugin.js.map +1 -0
- package/dist/src/plugins/SchemePlugin.d.ts +34 -0
- package/dist/src/plugins/SchemePlugin.js +47 -0
- package/dist/src/plugins/SchemePlugin.js.map +1 -0
- package/dist/src/plugins/ServicePlugin.d.ts +80 -0
- package/dist/src/plugins/ServicePlugin.js +168 -0
- package/dist/src/plugins/ServicePlugin.js.map +1 -0
- package/dist/src/plugins/ToolPlugin.d.ts +27 -0
- package/dist/src/plugins/ToolPlugin.js +37 -0
- package/dist/src/plugins/ToolPlugin.js.map +1 -0
- package/dist/src/plugins/index.d.ts +13 -0
- package/dist/src/plugins/index.js +14 -0
- package/dist/src/plugins/index.js.map +1 -0
- package/dist/src/plugins/plugins.d.ts +101 -0
- package/dist/src/plugins/plugins.js +292 -0
- package/dist/src/plugins/plugins.js.map +1 -0
- package/dist/src/process/Process.d.ts +108 -0
- package/dist/src/process/Process.js +335 -0
- package/dist/src/process/Process.js.map +1 -0
- package/dist/src/process/ProcessConnector.d.ts +24 -0
- package/dist/src/process/ProcessConnector.js +28 -0
- package/dist/src/process/ProcessConnector.js.map +1 -0
- package/dist/src/process/ProcessFile.d.ts +69 -0
- package/dist/src/process/ProcessFile.js +145 -0
- package/dist/src/process/ProcessFile.js.map +1 -0
- package/dist/src/process/ProcessHandler.d.ts +60 -0
- package/dist/src/process/ProcessHandler.js +73 -0
- package/dist/src/process/ProcessHandler.js.map +1 -0
- package/dist/src/process/ProcessStep.d.ts +52 -0
- package/dist/src/process/ProcessStep.js +78 -0
- package/dist/src/process/ProcessStep.js.map +1 -0
- package/dist/src/process/ProcessingSystem.d.ts +60 -0
- package/dist/src/process/ProcessingSystem.js +182 -0
- package/dist/src/process/ProcessingSystem.js.map +1 -0
- package/dist/src/process/index.d.ts +11 -0
- package/dist/src/process/index.js +12 -0
- package/dist/src/process/index.js.map +1 -0
- package/dist/src/reports/conversions.d.ts +8 -0
- package/dist/src/reports/conversions.js +47 -0
- package/dist/src/reports/conversions.js.map +1 -0
- package/dist/src/reports/index.d.ts +6 -0
- package/dist/src/reports/index.js +7 -0
- package/dist/src/reports/index.js.map +1 -0
- package/dist/src/server/ISPDemoServer.d.ts +43 -0
- package/dist/src/server/ISPDemoServer.js +112 -0
- package/dist/src/server/ISPDemoServer.js.map +1 -0
- package/dist/src/server/api.d.ts +15 -0
- package/dist/src/server/api.js +27 -0
- package/dist/src/server/api.js.map +1 -0
- package/dist/src/server/index.d.ts +7 -0
- package/dist/src/server/index.js +8 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/router.d.ts +5 -0
- package/dist/src/server/router.js +37 -0
- package/dist/src/server/router.js.map +1 -0
- package/dist/src/system.d.ts +27 -0
- package/dist/src/system.js +95 -0
- package/dist/src/system.js.map +1 -0
- package/dist/tests/TransactionRules.spec.d.ts +1 -0
- package/dist/tests/TransactionRules.spec.js +64 -0
- package/dist/tests/TransactionRules.spec.js.map +1 -0
- package/dist/tests/password.spec.d.ts +1 -0
- package/dist/tests/password.spec.js +8 -0
- package/dist/tests/password.spec.js.map +1 -0
- package/dist/tests/tokens.spec.d.ts +1 -0
- package/dist/tests/tokens.spec.js +49 -0
- package/dist/tests/tokens.spec.js.map +1 -0
- package/dist/tests/vault.spec.d.ts +1 -0
- package/dist/tests/vault.spec.js +19 -0
- package/dist/tests/vault.spec.js.map +1 -0
- package/package.json +3 -3
- package/src/import/TransactionImportHandler.ts +5 -1
- package/src/index.ts +0 -1
- package/src/testing/ProcessingSystemMock.ts +0 -45
- package/src/testing/UnitTestImportConnector.ts +0 -86
- package/src/testing/UnitTester.ts +0 -231
- package/src/testing/index.ts +0 -4
- package/src/testing/test-handlers.ts +0 -47
- package/tests/TransferAnalyzer-account-address.spec.ts +0 -87
- package/tests/TransferAnalyzer-buying-and-selling.spec.ts +0 -354
- package/tests/TransferAnalyzer-loans.spec.ts +0 -197
- package/tests/TransferAnalyzer-multiple-null-amounts.spec.ts +0 -181
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { AccountModelData, AccountNumber, ImporterModelData, TasenorPlugin, FilePath, PeriodModelData, ShortDate, TagModelData, ID } from '@tasenor/common';
|
|
2
|
+
import { ArgumentParser } from 'argparse';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
export type CommandArgument = string | null | undefined | string[];
|
|
5
|
+
/**
|
|
6
|
+
* Argument container type for commands.
|
|
7
|
+
*/
|
|
8
|
+
export type CommandArguments = Record<string, CommandArgument>;
|
|
9
|
+
/**
|
|
10
|
+
* Definition of argument name, corresponding environment variable and default value.
|
|
11
|
+
*/
|
|
12
|
+
export type CommandArgumentDefault = {
|
|
13
|
+
name: string;
|
|
14
|
+
envName: string;
|
|
15
|
+
defaultValue: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Data for creating entries.
|
|
19
|
+
*/
|
|
20
|
+
export type CommandEntryData = {
|
|
21
|
+
account_id: ID;
|
|
22
|
+
number?: AccountNumber;
|
|
23
|
+
amount: number;
|
|
24
|
+
description: string;
|
|
25
|
+
data?: Record<string, unknown>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* A command implementation base class.
|
|
29
|
+
*/
|
|
30
|
+
export declare class Command {
|
|
31
|
+
protected cli: any;
|
|
32
|
+
protected accounts: Record<AccountNumber, AccountModelData>;
|
|
33
|
+
protected accountsById: Record<number, AccountModelData>;
|
|
34
|
+
protected plugins: TasenorPlugin[];
|
|
35
|
+
protected importers: ImporterModelData[];
|
|
36
|
+
protected args: CommandArguments;
|
|
37
|
+
constructor(cli: any);
|
|
38
|
+
get verbose(): boolean;
|
|
39
|
+
get debug(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Add command specific arguments.
|
|
42
|
+
* @param parser
|
|
43
|
+
*/
|
|
44
|
+
addArguments(parser: ArgumentParser): void;
|
|
45
|
+
/**
|
|
46
|
+
* Set command arguments.
|
|
47
|
+
* @param args
|
|
48
|
+
*/
|
|
49
|
+
setArgs(args: CommandArguments): void;
|
|
50
|
+
/**
|
|
51
|
+
* Default output.
|
|
52
|
+
* @param data
|
|
53
|
+
*/
|
|
54
|
+
print(data: unknown): void;
|
|
55
|
+
/**
|
|
56
|
+
* Print out data structure according to the selected options.
|
|
57
|
+
* @param data
|
|
58
|
+
*/
|
|
59
|
+
out(prefix: any, data: any): void;
|
|
60
|
+
/**
|
|
61
|
+
* Entry point for running the command.
|
|
62
|
+
* @param args
|
|
63
|
+
*/
|
|
64
|
+
run(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Construct a form data instance for a file.
|
|
67
|
+
* @param filePath
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
formForFile(filePath: FilePath): FormData;
|
|
71
|
+
/**
|
|
72
|
+
* Call the GET API.
|
|
73
|
+
* @param api
|
|
74
|
+
*/
|
|
75
|
+
get<T>(api: string): Promise<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Call the GET UI API.
|
|
78
|
+
* @param api
|
|
79
|
+
*/
|
|
80
|
+
getUi<T>(api: string): Promise<T>;
|
|
81
|
+
/**
|
|
82
|
+
* Call the DELETE API.
|
|
83
|
+
* @param api
|
|
84
|
+
*/
|
|
85
|
+
delete<T>(api: string): Promise<T>;
|
|
86
|
+
/**
|
|
87
|
+
* Call the DELETE API.
|
|
88
|
+
* @param api
|
|
89
|
+
*/
|
|
90
|
+
deleteUi<T>(api: string, args?: Record<string, unknown> | undefined): Promise<T>;
|
|
91
|
+
/**
|
|
92
|
+
* Call the PATCH API.
|
|
93
|
+
* @param api
|
|
94
|
+
*/
|
|
95
|
+
patch<T>(api: string, data: FormData | Record<string, unknown>): Promise<T>;
|
|
96
|
+
/**
|
|
97
|
+
* Call the POST API.
|
|
98
|
+
* @param api
|
|
99
|
+
*/
|
|
100
|
+
post<T>(api: string, data: FormData | Record<string, unknown>): Promise<T>;
|
|
101
|
+
/**
|
|
102
|
+
* Call the POST UI API.
|
|
103
|
+
* @param api
|
|
104
|
+
*/
|
|
105
|
+
postUi<T>(api: string, data: FormData | Record<string, unknown>): Promise<T>;
|
|
106
|
+
/**
|
|
107
|
+
* An alternative POST call to upload file, when its path is known.
|
|
108
|
+
* @param api
|
|
109
|
+
* @param filePath
|
|
110
|
+
* @returns
|
|
111
|
+
*/
|
|
112
|
+
postUpload<T>(api: string, filePath: FilePath): Promise<T>;
|
|
113
|
+
/**
|
|
114
|
+
* Download URL to a file.
|
|
115
|
+
*/
|
|
116
|
+
getDownload(api: string, filePath: FilePath): Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Execute member function based on the given argument.
|
|
119
|
+
*/
|
|
120
|
+
runBy(op: string): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Ensure string argument.
|
|
123
|
+
* @param arg
|
|
124
|
+
*/
|
|
125
|
+
str(arg: CommandArgument): string;
|
|
126
|
+
/**
|
|
127
|
+
* Ensure numeric argument.
|
|
128
|
+
* @param arg
|
|
129
|
+
*/
|
|
130
|
+
num(arg: CommandArgument): number;
|
|
131
|
+
/**
|
|
132
|
+
* Convert year, date or number to period ID.
|
|
133
|
+
* @param arg
|
|
134
|
+
*/
|
|
135
|
+
periodId(db: CommandArgument, periodArg: CommandArgument): Promise<ID>;
|
|
136
|
+
/**
|
|
137
|
+
* Ensure that there is only one period in the DB and return its ID.
|
|
138
|
+
* @param dbArg
|
|
139
|
+
* @returns
|
|
140
|
+
*/
|
|
141
|
+
singlePeriod(dbArg: CommandArgument): Promise<PeriodModelData>;
|
|
142
|
+
/**
|
|
143
|
+
* Read in accounts if not yet read.
|
|
144
|
+
*/
|
|
145
|
+
readAccounts(dbArg: CommandArgument): Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Verify that the given number is valid account and return its ID.
|
|
148
|
+
* @param dbArg
|
|
149
|
+
* @param accountArg
|
|
150
|
+
*/
|
|
151
|
+
accountId(dbArg: CommandArgument, accountArg: CommandArgument): Promise<ID>;
|
|
152
|
+
/**
|
|
153
|
+
* Verify that argument is one or more entry descriptions.
|
|
154
|
+
* @param entryArg
|
|
155
|
+
*/
|
|
156
|
+
entries(dbArg: CommandArgument, entryArg: CommandArgument): Promise<CommandEntryData[]>;
|
|
157
|
+
/**
|
|
158
|
+
* Verify that the argument is proper date.
|
|
159
|
+
* @param date
|
|
160
|
+
*/
|
|
161
|
+
date(dateArg: CommandArgument): ShortDate;
|
|
162
|
+
/**
|
|
163
|
+
* Heuristically parse string to JSON value or string if not parseable.
|
|
164
|
+
* @param value
|
|
165
|
+
*/
|
|
166
|
+
value(value: CommandArgument): unknown;
|
|
167
|
+
/**
|
|
168
|
+
* Parse either direct JSON data argument or read in file, if string starts with `@`.
|
|
169
|
+
* @param data
|
|
170
|
+
*/
|
|
171
|
+
jsonData(dataArg: CommandArgument): Promise<Record<string, unknown>>;
|
|
172
|
+
/**
|
|
173
|
+
* Read in plugin data if not yet read and return info about the plugin.
|
|
174
|
+
* @param pluginArg
|
|
175
|
+
*/
|
|
176
|
+
plugin(pluginArg: CommandArgument): Promise<TasenorPlugin | TasenorPlugin[]>;
|
|
177
|
+
/**
|
|
178
|
+
* Get the importer.
|
|
179
|
+
* @param nameArg
|
|
180
|
+
*/
|
|
181
|
+
importer(dbArg: CommandArgument, nameArg: CommandArgument): Promise<ImporterModelData>;
|
|
182
|
+
/**
|
|
183
|
+
* Find the named tag or throw an error.
|
|
184
|
+
* @param name
|
|
185
|
+
*/
|
|
186
|
+
tag(db: CommandArgument, name: CommandArgument): Promise<TagModelData>;
|
|
187
|
+
/**
|
|
188
|
+
* Show help.
|
|
189
|
+
*/
|
|
190
|
+
help(): void;
|
|
191
|
+
}
|
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
/**
|
|
6
|
+
* A command implementation base class.
|
|
7
|
+
*/
|
|
8
|
+
export class Command {
|
|
9
|
+
cli;
|
|
10
|
+
accounts;
|
|
11
|
+
accountsById;
|
|
12
|
+
plugins;
|
|
13
|
+
importers;
|
|
14
|
+
args;
|
|
15
|
+
constructor(cli) {
|
|
16
|
+
this.cli = cli;
|
|
17
|
+
}
|
|
18
|
+
get verbose() {
|
|
19
|
+
return !!this.args.verbose;
|
|
20
|
+
}
|
|
21
|
+
get debug() {
|
|
22
|
+
return !!this.args.debug;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Add command specific arguments.
|
|
26
|
+
* @param parser
|
|
27
|
+
*/
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
29
|
+
addArguments(parser) {
|
|
30
|
+
// Command subclass implements.
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Set command arguments.
|
|
34
|
+
* @param args
|
|
35
|
+
*/
|
|
36
|
+
setArgs(args) {
|
|
37
|
+
this.args = args;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Default output.
|
|
41
|
+
* @param data
|
|
42
|
+
*/
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
|
+
print(data) {
|
|
45
|
+
throw new Error(`Class ${this.constructor.name} does not implement print().`);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Print out data structure according to the selected options.
|
|
49
|
+
* @param data
|
|
50
|
+
*/
|
|
51
|
+
out(prefix, data) {
|
|
52
|
+
if (this.args.json) {
|
|
53
|
+
console.log(JSON.stringify(data, null, 2));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (!this.verbose) {
|
|
57
|
+
try {
|
|
58
|
+
this.print(data);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
// If not implemented, do default verbose output.
|
|
63
|
+
if (!/does not implement print/.test(`${err}`)) {
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const print = (prefix, obj) => {
|
|
69
|
+
if (typeof obj === 'object') {
|
|
70
|
+
if (obj === null) {
|
|
71
|
+
console.log(`${prefix} = null`);
|
|
72
|
+
}
|
|
73
|
+
else if (obj instanceof Array) {
|
|
74
|
+
for (let i = 0; i < obj.length; i++) {
|
|
75
|
+
console.log(`${prefix}[${i}]`);
|
|
76
|
+
print(` ${prefix}[${i}]`, obj[i]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
for (const key of Object.keys(obj)) {
|
|
81
|
+
print(` ${prefix}.${key}`, obj[key]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
console.log(`${prefix} =`, obj);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
print(prefix, data);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Entry point for running the command.
|
|
94
|
+
* @param args
|
|
95
|
+
*/
|
|
96
|
+
async run() {
|
|
97
|
+
throw new Error(`A command ${this.constructor.name} does not implement run().`);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Construct a form data instance for a file.
|
|
101
|
+
* @param filePath
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
formForFile(filePath) {
|
|
105
|
+
const form = new FormData();
|
|
106
|
+
const buf = fs.readFileSync(filePath);
|
|
107
|
+
form.append('file', buf, path.basename(filePath));
|
|
108
|
+
return form;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Call the GET API.
|
|
112
|
+
* @param api
|
|
113
|
+
*/
|
|
114
|
+
async get(api) {
|
|
115
|
+
await this.cli.login();
|
|
116
|
+
const resp = await this.cli.request('GET', api);
|
|
117
|
+
if (!resp.success) {
|
|
118
|
+
throw new Error(`Call to GET ${api} failed: ${JSON.stringify(resp)}`);
|
|
119
|
+
}
|
|
120
|
+
return resp.data;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Call the GET UI API.
|
|
124
|
+
* @param api
|
|
125
|
+
*/
|
|
126
|
+
async getUi(api) {
|
|
127
|
+
await this.cli.login();
|
|
128
|
+
const resp = await this.cli.requestUi('GET', api);
|
|
129
|
+
if (!resp.success) {
|
|
130
|
+
throw new Error(`Call to GET UI ${api} failed: ${JSON.stringify(resp)}`);
|
|
131
|
+
}
|
|
132
|
+
return resp.data;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Call the DELETE API.
|
|
136
|
+
* @param api
|
|
137
|
+
*/
|
|
138
|
+
async delete(api) {
|
|
139
|
+
await this.cli.login();
|
|
140
|
+
const resp = await this.cli.request('DELETE', api);
|
|
141
|
+
if (!resp.success) {
|
|
142
|
+
throw new Error(`Call to DELETE ${api} failed: ${JSON.stringify(resp)}`);
|
|
143
|
+
}
|
|
144
|
+
return resp.data;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Call the DELETE API.
|
|
148
|
+
* @param api
|
|
149
|
+
*/
|
|
150
|
+
async deleteUi(api, args = undefined) {
|
|
151
|
+
await this.cli.login();
|
|
152
|
+
const resp = await this.cli.requestUi('DELETE', api, args);
|
|
153
|
+
if (!resp.success) {
|
|
154
|
+
throw new Error(`Call to DELETE UI ${api} failed: ${JSON.stringify(resp)}`);
|
|
155
|
+
}
|
|
156
|
+
return resp.data;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Call the PATCH API.
|
|
160
|
+
* @param api
|
|
161
|
+
*/
|
|
162
|
+
async patch(api, data) {
|
|
163
|
+
await this.cli.login();
|
|
164
|
+
const resp = await this.cli.request('PATCH', api, data);
|
|
165
|
+
if (!resp.success) {
|
|
166
|
+
throw new Error(`Call to PATCH ${api} failed: ${JSON.stringify(resp)}`);
|
|
167
|
+
}
|
|
168
|
+
return resp.data;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Call the POST API.
|
|
172
|
+
* @param api
|
|
173
|
+
*/
|
|
174
|
+
async post(api, data) {
|
|
175
|
+
await this.cli.login();
|
|
176
|
+
const resp = await this.cli.request('POST', api, data);
|
|
177
|
+
if (!resp.success) {
|
|
178
|
+
throw new Error(`Call to POST ${api} failed: ${JSON.stringify(resp)}`);
|
|
179
|
+
}
|
|
180
|
+
return resp.data;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Call the POST UI API.
|
|
184
|
+
* @param api
|
|
185
|
+
*/
|
|
186
|
+
async postUi(api, data) {
|
|
187
|
+
await this.cli.login();
|
|
188
|
+
const resp = await this.cli.requestUi('POST', api, data);
|
|
189
|
+
if (!resp.success) {
|
|
190
|
+
throw new Error(`Call to POST UI ${api} failed: ${JSON.stringify(resp)}`);
|
|
191
|
+
}
|
|
192
|
+
return resp.data;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* An alternative POST call to upload file, when its path is known.
|
|
196
|
+
* @param api
|
|
197
|
+
* @param filePath
|
|
198
|
+
* @returns
|
|
199
|
+
*/
|
|
200
|
+
async postUpload(api, filePath) {
|
|
201
|
+
const form = this.formForFile(filePath);
|
|
202
|
+
return this.post(api, form);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Download URL to a file.
|
|
206
|
+
*/
|
|
207
|
+
async getDownload(api, filePath) {
|
|
208
|
+
await this.cli.login();
|
|
209
|
+
const resp = await axios({
|
|
210
|
+
url: `${this.cli.api}${api}`,
|
|
211
|
+
method: 'GET',
|
|
212
|
+
responseType: 'arraybuffer',
|
|
213
|
+
headers: {
|
|
214
|
+
Authorization: `Bearer ${this.cli.token}`
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
fs.writeFileSync(filePath, resp.data);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Execute member function based on the given argument.
|
|
221
|
+
*/
|
|
222
|
+
async runBy(op) {
|
|
223
|
+
const cmd = this.args[op];
|
|
224
|
+
if (!cmd) {
|
|
225
|
+
this.help();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (typeof cmd !== 'string') {
|
|
229
|
+
throw new Error(`Invalid operation argument ${JSON.stringify(cmd)}.`);
|
|
230
|
+
}
|
|
231
|
+
if (!this[cmd]) {
|
|
232
|
+
console.log(this[cmd]);
|
|
233
|
+
throw new Error(`There is no member function '${cmd}' in command class '${this.constructor.name}'.`);
|
|
234
|
+
}
|
|
235
|
+
await this[cmd]();
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Ensure string argument.
|
|
239
|
+
* @param arg
|
|
240
|
+
*/
|
|
241
|
+
str(arg) {
|
|
242
|
+
if (arg === null || arg === undefined) {
|
|
243
|
+
return '';
|
|
244
|
+
}
|
|
245
|
+
if (typeof arg === 'string') {
|
|
246
|
+
return arg;
|
|
247
|
+
}
|
|
248
|
+
return arg[0];
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Ensure numeric argument.
|
|
252
|
+
* @param arg
|
|
253
|
+
*/
|
|
254
|
+
num(arg) {
|
|
255
|
+
if (arg === null || arg === undefined) {
|
|
256
|
+
return 0;
|
|
257
|
+
}
|
|
258
|
+
return parseFloat(this.str(arg));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Convert year, date or number to period ID.
|
|
262
|
+
* @param arg
|
|
263
|
+
*/
|
|
264
|
+
async periodId(db, periodArg) {
|
|
265
|
+
if (!db) {
|
|
266
|
+
throw new Error(`Invalid database argument ${JSON.stringify(db)}`);
|
|
267
|
+
}
|
|
268
|
+
const period = this.str(periodArg);
|
|
269
|
+
if (!period) {
|
|
270
|
+
throw new Error(`Invalid period argument ${JSON.stringify(period)}`);
|
|
271
|
+
}
|
|
272
|
+
let periods = await this.get(`/db/${db}/period`);
|
|
273
|
+
if (/^\d{4}$/.test(period)) {
|
|
274
|
+
const date = `${period}-06-15`;
|
|
275
|
+
periods = periods.filter(p => p.start_date <= date && date <= p.end_date);
|
|
276
|
+
}
|
|
277
|
+
else if (/^\d{4}-\d{2}-\d{2}$/.test(period)) {
|
|
278
|
+
periods = periods.filter(p => p.start_date <= period && period <= p.end_date);
|
|
279
|
+
}
|
|
280
|
+
else if (/^\d+$/.test(period)) {
|
|
281
|
+
const id = parseInt(period);
|
|
282
|
+
periods = periods.filter(p => p.id === id);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
throw new Error(`Invalid period argument ${JSON.stringify(period)}`);
|
|
286
|
+
}
|
|
287
|
+
if (periods.length > 1) {
|
|
288
|
+
throw new Error(`Too many periods match to ${JSON.stringify(period)}`);
|
|
289
|
+
}
|
|
290
|
+
if (!periods.length) {
|
|
291
|
+
throw new Error(`No periods found matching ${JSON.stringify(period)}`);
|
|
292
|
+
}
|
|
293
|
+
return periods[0].id;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Ensure that there is only one period in the DB and return its ID.
|
|
297
|
+
* @param dbArg
|
|
298
|
+
* @returns
|
|
299
|
+
*/
|
|
300
|
+
async singlePeriod(dbArg) {
|
|
301
|
+
const period = await this.get(`/db/${this.str(dbArg)}/period`);
|
|
302
|
+
if (period.length < 1) {
|
|
303
|
+
throw new Error('There are no periods in the database.');
|
|
304
|
+
}
|
|
305
|
+
if (period.length > 1) {
|
|
306
|
+
throw new Error('There are too many periods in the database to set initial balance.');
|
|
307
|
+
}
|
|
308
|
+
return period[0];
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Read in accounts if not yet read.
|
|
312
|
+
*/
|
|
313
|
+
async readAccounts(dbArg) {
|
|
314
|
+
if (!this.accounts) {
|
|
315
|
+
this.accounts = {};
|
|
316
|
+
this.accountsById = {};
|
|
317
|
+
const accounts = await this.get(`/db/${this.str(dbArg)}/account`);
|
|
318
|
+
for (const account of accounts) {
|
|
319
|
+
this.accounts[account.number] = account;
|
|
320
|
+
this.accountsById[account.id || 0] = account;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Verify that the given number is valid account and return its ID.
|
|
326
|
+
* @param dbArg
|
|
327
|
+
* @param accountArg
|
|
328
|
+
*/
|
|
329
|
+
async accountId(dbArg, accountArg) {
|
|
330
|
+
await this.readAccounts(dbArg);
|
|
331
|
+
const num = this.str(accountArg);
|
|
332
|
+
if (!this.accounts[num]) {
|
|
333
|
+
throw new Error(`No account found matching ${JSON.stringify(accountArg)}`);
|
|
334
|
+
}
|
|
335
|
+
return this.accounts[num].id;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Verify that argument is one or more entry descriptions.
|
|
339
|
+
* @param entryArg
|
|
340
|
+
*/
|
|
341
|
+
async entries(dbArg, entryArg) {
|
|
342
|
+
if (!entryArg) {
|
|
343
|
+
throw new Error(`Invalid entry argument ${JSON.stringify(entryArg)}.`);
|
|
344
|
+
}
|
|
345
|
+
const entry = typeof entryArg === 'string' ? [entryArg] : entryArg;
|
|
346
|
+
const ret = [];
|
|
347
|
+
for (const e of entry) {
|
|
348
|
+
const match = /^\s*(\d+)\s+(.+?)\s+([-+]?\d+([,.]\d+)?)(\s+\{.*\})?$/.exec(e);
|
|
349
|
+
if (!match) {
|
|
350
|
+
throw new Error(`Invalid transaction line ${JSON.stringify(e)}`);
|
|
351
|
+
}
|
|
352
|
+
const amount = Math.round(parseFloat(match[3].replace(',', '.')) * 100);
|
|
353
|
+
let data;
|
|
354
|
+
if (match[5]) {
|
|
355
|
+
try {
|
|
356
|
+
data = JSON.parse(match[5]);
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
throw new Error(`Parsing JSON '${match[5]}' failed.`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
ret.push({
|
|
363
|
+
account_id: await this.accountId(dbArg, match[1]),
|
|
364
|
+
number: match[1],
|
|
365
|
+
amount,
|
|
366
|
+
description: match[2],
|
|
367
|
+
data
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
return ret;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Verify that the argument is proper date.
|
|
374
|
+
* @param date
|
|
375
|
+
*/
|
|
376
|
+
date(dateArg) {
|
|
377
|
+
const date = this.str(dateArg);
|
|
378
|
+
if (!date || !/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
379
|
+
throw new Error(`Invalid date argument ${JSON.stringify(dateArg)}`);
|
|
380
|
+
}
|
|
381
|
+
return date;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Heuristically parse string to JSON value or string if not parseable.
|
|
385
|
+
* @param value
|
|
386
|
+
*/
|
|
387
|
+
value(value) {
|
|
388
|
+
value = this.str(value);
|
|
389
|
+
try {
|
|
390
|
+
return JSON.parse(value);
|
|
391
|
+
}
|
|
392
|
+
catch (err) {
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Parse either direct JSON data argument or read in file, if string starts with `@`.
|
|
398
|
+
* @param data
|
|
399
|
+
*/
|
|
400
|
+
async jsonData(dataArg) {
|
|
401
|
+
if (dataArg instanceof Array) {
|
|
402
|
+
const ret = {};
|
|
403
|
+
for (const data of dataArg) {
|
|
404
|
+
Object.assign(ret, await this.jsonData(data));
|
|
405
|
+
}
|
|
406
|
+
return ret;
|
|
407
|
+
}
|
|
408
|
+
if (!dataArg || typeof dataArg !== 'string') {
|
|
409
|
+
throw new Error(`Invalid JSON data argument ${JSON.stringify(dataArg)}.`);
|
|
410
|
+
}
|
|
411
|
+
let data;
|
|
412
|
+
if (dataArg[0] === '@') {
|
|
413
|
+
data = fs.readFileSync(dataArg.substring(1)).toString('utf-8');
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
data = dataArg;
|
|
417
|
+
}
|
|
418
|
+
try {
|
|
419
|
+
return JSON.parse(data);
|
|
420
|
+
}
|
|
421
|
+
catch (err) {
|
|
422
|
+
throw new Error(`Failed to parse JSON ${data.substr(0, 1000)}.`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Read in plugin data if not yet read and return info about the plugin.
|
|
427
|
+
* @param pluginArg
|
|
428
|
+
*/
|
|
429
|
+
async plugin(pluginArg) {
|
|
430
|
+
if (!this.plugins) {
|
|
431
|
+
this.plugins = await this.getUi('/internal/plugins');
|
|
432
|
+
}
|
|
433
|
+
if (pluginArg instanceof Array) {
|
|
434
|
+
const result = [];
|
|
435
|
+
for (const plugin of pluginArg) {
|
|
436
|
+
result.push(await this.plugin(plugin));
|
|
437
|
+
}
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
const code = this.str(pluginArg);
|
|
441
|
+
const plugin = this.plugins.filter(p => p.code === code);
|
|
442
|
+
if (!plugin.length) {
|
|
443
|
+
throw new Error(`Cannot find plugin '${code}'.`);
|
|
444
|
+
}
|
|
445
|
+
return plugin[0];
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Get the importer.
|
|
449
|
+
* @param nameArg
|
|
450
|
+
*/
|
|
451
|
+
async importer(dbArg, nameArg) {
|
|
452
|
+
if (!this.importers) {
|
|
453
|
+
this.importers = await this.get(`/db/${this.str(dbArg)}/importer`);
|
|
454
|
+
}
|
|
455
|
+
const name = this.str(nameArg);
|
|
456
|
+
const importer = this.importers.filter(p => p.name === name);
|
|
457
|
+
if (!importer.length) {
|
|
458
|
+
throw new Error(`Cannot find importer '${name}'.`);
|
|
459
|
+
}
|
|
460
|
+
return importer[0];
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Find the named tag or throw an error.
|
|
464
|
+
* @param name
|
|
465
|
+
*/
|
|
466
|
+
async tag(db, name) {
|
|
467
|
+
const resp = await this.get(`/db/${db}/tags`);
|
|
468
|
+
const match = resp.filter(tag => tag.tag === name);
|
|
469
|
+
if (!match.length) {
|
|
470
|
+
throw new Error(`Cannot find a tag '${name}.`);
|
|
471
|
+
}
|
|
472
|
+
return match[0];
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Show help.
|
|
476
|
+
*/
|
|
477
|
+
help() {
|
|
478
|
+
const args = this.cli.originalArgs.concat(['-h']);
|
|
479
|
+
this.cli.run([], args);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"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"}
|