bkper 4.0.1 → 4.0.2
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/CHANGELOG.md +48 -28
- package/lib/bkper-factory.d.ts.map +1 -1
- package/lib/bkper-factory.js +5 -0
- package/lib/bkper-factory.js.map +1 -1
- package/lib/cli.js +100 -32
- package/lib/cli.js.map +1 -1
- package/lib/commands/accounts/create.d.ts.map +1 -1
- package/lib/commands/accounts/create.js +16 -5
- package/lib/commands/accounts/create.js.map +1 -1
- package/lib/commands/accounts/update.d.ts.map +1 -1
- package/lib/commands/accounts/update.js +13 -5
- package/lib/commands/accounts/update.js.map +1 -1
- package/lib/commands/books/create.d.ts.map +1 -1
- package/lib/commands/books/create.js +10 -2
- package/lib/commands/books/create.js.map +1 -1
- package/lib/commands/books/update.d.ts.map +1 -1
- package/lib/commands/books/update.js +13 -5
- package/lib/commands/books/update.js.map +1 -1
- package/lib/commands/groups/create.d.ts.map +1 -1
- package/lib/commands/groups/create.js +16 -5
- package/lib/commands/groups/create.js.map +1 -1
- package/lib/commands/groups/update.d.ts.map +1 -1
- package/lib/commands/groups/update.js +13 -5
- package/lib/commands/groups/update.js.map +1 -1
- package/lib/commands/transactions/create.d.ts.map +1 -1
- package/lib/commands/transactions/create.js +23 -7
- package/lib/commands/transactions/create.js.map +1 -1
- package/lib/commands/transactions/merge.d.ts.map +1 -1
- package/lib/commands/transactions/merge.js +6 -2
- package/lib/commands/transactions/merge.js.map +1 -1
- package/lib/commands/transactions/update.d.ts.map +1 -1
- package/lib/commands/transactions/update.js +23 -7
- package/lib/commands/transactions/update.js.map +1 -1
- package/lib/render/table-formatter.d.ts.map +1 -1
- package/lib/render/table-formatter.js +22 -4
- package/lib/render/table-formatter.js.map +1 -1
- package/lib/utils/validation.d.ts +38 -0
- package/lib/utils/validation.d.ts.map +1 -0
- package/lib/utils/validation.js +46 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,45 +4,65 @@
|
|
|
4
4
|
|
|
5
5
|
### **February 2026**
|
|
6
6
|
|
|
7
|
-
**CLI**
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
7
|
+
- **CLI**
|
|
8
|
+
- Table-formatted output is now the default for all commands
|
|
9
|
+
- Added `--json` global flag to output raw JSON instead of formatted tables
|
|
10
|
+
- Added `-b, --book` option for scoping commands to a specific [Book](https://bkper.com/docs)
|
|
11
|
+
- Added `-p, --properties` repeatable flag for setting custom properties as `key=value` pairs
|
|
12
|
+
- [Transaction](https://bkper.com/docs) tables show formatted dates and values with IDs
|
|
13
|
+
- [Group](https://bkper.com/docs) tables render as indented trees showing hierarchy
|
|
14
|
+
- Single-item commands display as indented key-value pairs
|
|
15
|
+
- Removed MCP server — now maintained as a separate project
|
|
16
|
+
- **Data Management**
|
|
17
|
+
- Added [Book](https://bkper.com/docs) create command
|
|
18
|
+
- Added [Collection](https://bkper.com/docs) commands: create, list, get, update, delete, add-book, remove-book
|
|
19
|
+
- Added [Transaction](https://bkper.com/docs) update command
|
|
20
|
+
- Renamed `balance get` to `balance list` for consistency
|
|
21
|
+
- **Authentication**
|
|
22
|
+
- Switched to PKCE-based OAuth flow — no client secret required
|
|
23
|
+
- Branded OAuth callback pages for a polished sign-in experience
|
|
24
|
+
- **App Development**
|
|
25
|
+
- Local development now uses Cloudflare Tunnel for event handling — no cloud deployment needed during development
|
|
26
|
+
- Renamed `dev` environment to `preview` for clarity
|
|
27
|
+
- Added `--no-open` flag to suppress automatic browser launch during dev
|
|
28
|
+
|
|
29
|
+
### **January 2026**
|
|
30
|
+
|
|
31
|
+
- **App Platform**
|
|
32
|
+
- Added [`app init`](https://bkper.com/docs) command to scaffold new apps from template
|
|
33
|
+
- Added [`app deploy`](https://bkper.com/docs) and [`app undeploy`](https://bkper.com/docs) commands for managing deployments
|
|
34
|
+
- Added [`app status`](https://bkper.com/docs) to view current deployment information
|
|
35
|
+
- Added [`app dev`](https://bkper.com/docs) and [`app build`](https://bkper.com/docs) commands for local development and build workflows
|
|
36
|
+
- Added [`app secrets`](https://bkper.com/docs) management — put, list, and delete secrets for your apps
|
|
37
|
+
- Added [`app sync`](https://bkper.com/docs) command to push `bkper.yaml` configuration to the platform
|
|
38
|
+
- Support for shared packages in monorepo setups with hot reload
|
|
39
|
+
- Asset file uploads included in deployments
|
|
40
|
+
- Migrated app configuration from `bkperapp.yaml` to `bkper.yaml`
|
|
17
41
|
|
|
18
42
|
## 2025
|
|
19
43
|
|
|
20
44
|
### **October 2025**
|
|
21
45
|
|
|
22
|
-
**MCP Server**
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- Improved transaction data responses for better AI assistant integration
|
|
46
|
+
- **MCP Server**
|
|
47
|
+
- Added smart [Transaction](https://bkper.com/docs) merging — combine multiple transactions based on date and account matching
|
|
48
|
+
- Simplified [Transaction](https://bkper.com/docs) creation — accounts are now optional for recording simple income and expenses
|
|
49
|
+
- Improved transaction data responses for better AI assistant integration
|
|
27
50
|
|
|
28
51
|
### **September 2025**
|
|
29
52
|
|
|
30
|
-
**MCP Server**
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
- Fixed credential storage to follow standard configuration directories
|
|
53
|
+
- **MCP Server**
|
|
54
|
+
- Streamlined transaction data for cleaner AI assistant responses
|
|
55
|
+
- Fixed credential storage to follow standard configuration directories
|
|
34
56
|
|
|
35
57
|
### **July 2025**
|
|
36
58
|
|
|
37
|
-
**MCP Server**
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
- Added setup instructions for Claude Desktop and other AI tools
|
|
59
|
+
- **MCP Server**
|
|
60
|
+
- Added monthly and year-to-date [Balance](https://bkper.com/docs) analysis for AI assistants
|
|
61
|
+
- Improved date filtering with `before:` operator
|
|
62
|
+
- Added setup instructions for Claude Desktop and other AI tools
|
|
42
63
|
|
|
43
64
|
### **June 2025**
|
|
44
65
|
|
|
45
|
-
**
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
- Added book name filtering to quickly find specific books
|
|
66
|
+
- **CLI**
|
|
67
|
+
- Introduced MCP server — connect AI assistants to your Bkper [Books](https://bkper.com/docs) with `bkper mcp start`
|
|
68
|
+
- Added [Book](https://bkper.com/docs) name filtering to quickly find specific books
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bkper-factory.d.ts","sourceRoot":"","sources":["../src/bkper-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,KAAK,CAiBxC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,
|
|
1
|
+
{"version":3,"file":"bkper-factory.d.ts","sourceRoot":"","sources":["../src/bkper-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,KAAK,CAiBxC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,SAezB"}
|
package/lib/bkper-factory.js
CHANGED
|
@@ -43,6 +43,11 @@ export function setupBkper() {
|
|
|
43
43
|
Bkper.setConfig({
|
|
44
44
|
apiKeyProvider: apiKey ? () => __awaiter(this, void 0, void 0, function* () { return apiKey; }) : undefined,
|
|
45
45
|
oauthTokenProvider: () => getOAuthToken(),
|
|
46
|
+
requestHeadersProvider: () => __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
return {
|
|
48
|
+
'bkper-agent-id': 'bkper-cli',
|
|
49
|
+
};
|
|
50
|
+
}),
|
|
46
51
|
//@ts-ignore
|
|
47
52
|
apiBaseUrl,
|
|
48
53
|
});
|
package/lib/bkper-factory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bkper-factory.js","sourceRoot":"","sources":["../src/bkper-factory.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,IAAI,uBAAuB,GAAsB,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC5B,8CAA8C;IAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAK,UAAkB,CAAC,WAAW,EAAE,CAAC;QACrE,OAAQ,UAAkB,CAAC,WAAW,IAAI,KAAK,CAAC;IACpD,CAAC;IAED,+CAA+C;IAC/C,IAAI,uBAAuB,EAAE,CAAC;QAC1B,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,sCAAsC;IACtC,UAAU,EAAE,CAAC;IACb,gCAAgC;IAChC,uBAAuB,GAAG,IAAI,KAAK,EAAE,CAAC;IAEtC,OAAO,uBAAuB,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU;IACtB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAE7C,KAAK,CAAC,SAAS,CAAC;QACZ,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,GAAS,EAAE,gDAAC,OAAA,MAAM,CAAA,GAAA,CAAC,CAAC,CAAC,SAAS;QACvD,kBAAkB,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;QACzC,YAAY;QACZ,UAAU;KACb,CAAC,CAAC;AACP,CAAC"}
|
|
1
|
+
{"version":3,"file":"bkper-factory.js","sourceRoot":"","sources":["../src/bkper-factory.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,IAAI,uBAAuB,GAAsB,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC5B,8CAA8C;IAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAK,UAAkB,CAAC,WAAW,EAAE,CAAC;QACrE,OAAQ,UAAkB,CAAC,WAAW,IAAI,KAAK,CAAC;IACpD,CAAC;IAED,+CAA+C;IAC/C,IAAI,uBAAuB,EAAE,CAAC;QAC1B,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED,sCAAsC;IACtC,UAAU,EAAE,CAAC;IACb,gCAAgC;IAChC,uBAAuB,GAAG,IAAI,KAAK,EAAE,CAAC;IAEtC,OAAO,uBAAuB,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU;IACtB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAE7C,KAAK,CAAC,SAAS,CAAC;QACZ,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,GAAS,EAAE,gDAAC,OAAA,MAAM,CAAA,GAAA,CAAC,CAAC,CAAC,SAAS;QACvD,kBAAkB,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;QACzC,sBAAsB,EAAE,GAAS,EAAE;YAC/B,OAAO;gBACH,gBAAgB,EAAE,WAAW;aAChC,CAAC;QACN,CAAC,CAAA;QACD,YAAY;QACZ,UAAU;KACb,CAAC,CAAC;AACP,CAAC"}
|
package/lib/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
import 'dotenv/config'; // Must be first to load env vars before other imports
|
|
12
12
|
import { program } from 'commander';
|
|
13
|
-
import {
|
|
13
|
+
import { AccountsDataTableBuilder, GroupsDataTableBuilder, } from 'bkper-js';
|
|
14
14
|
import { login, logout } from './auth/local-auth-service.js';
|
|
15
15
|
import { setupBkper } from './bkper-factory.js';
|
|
16
16
|
import { listApps, syncApp, deployApp, undeployApp, statusApp, initApp, secretsPut, secretsList, secretsDelete, dev, build, installApp, uninstallApp, } from './commands/apps/index.js';
|
|
@@ -21,6 +21,7 @@ import { listTransactions, createTransaction, updateTransaction, postTransaction
|
|
|
21
21
|
import { listBalancesMatrix } from './commands/balances/index.js';
|
|
22
22
|
import { listCollections, getCollection, createCollection, updateCollection, deleteCollection, addBookToCollection, removeBookFromCollection, } from './commands/collections/index.js';
|
|
23
23
|
import { renderTable, renderItem } from './render/index.js';
|
|
24
|
+
import { validateRequiredOptions, throwIfErrors } from './utils/validation.js';
|
|
24
25
|
function collectProperty(value, previous) {
|
|
25
26
|
return previous ? [...previous, value] : [value];
|
|
26
27
|
}
|
|
@@ -221,9 +222,10 @@ secretsCommand
|
|
|
221
222
|
appCommand
|
|
222
223
|
.command('install <appId>')
|
|
223
224
|
.description('Install an app into a book')
|
|
224
|
-
.
|
|
225
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
225
226
|
.action((appId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
226
227
|
try {
|
|
228
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
227
229
|
setupBkper();
|
|
228
230
|
const integration = yield installApp(options.book, appId);
|
|
229
231
|
renderItem(integration.json(), isJson());
|
|
@@ -236,9 +238,10 @@ appCommand
|
|
|
236
238
|
appCommand
|
|
237
239
|
.command('uninstall <appId>')
|
|
238
240
|
.description('Uninstall an app from a book')
|
|
239
|
-
.
|
|
241
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
240
242
|
.action((appId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
241
243
|
try {
|
|
244
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
242
245
|
setupBkper();
|
|
243
246
|
const integration = yield uninstallApp(options.book, appId);
|
|
244
247
|
renderItem(integration.json(), isJson());
|
|
@@ -255,6 +258,7 @@ bookCommand
|
|
|
255
258
|
.description('List all books')
|
|
256
259
|
.option('-q, --query <query>', 'Search query')
|
|
257
260
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
261
|
+
var _a;
|
|
258
262
|
try {
|
|
259
263
|
setupBkper();
|
|
260
264
|
const books = yield listBooks(options.query);
|
|
@@ -262,7 +266,33 @@ bookCommand
|
|
|
262
266
|
console.log(JSON.stringify(books.map(b => b.json()), null, 2));
|
|
263
267
|
}
|
|
264
268
|
else {
|
|
265
|
-
|
|
269
|
+
if (books.length === 0) {
|
|
270
|
+
console.log('No results found.');
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
books.sort((a, b) => {
|
|
274
|
+
var _a, _b;
|
|
275
|
+
const collA = (_a = a.getCollection()) === null || _a === void 0 ? void 0 : _a.getName();
|
|
276
|
+
const collB = (_b = b.getCollection()) === null || _b === void 0 ? void 0 : _b.getName();
|
|
277
|
+
if (collA && !collB)
|
|
278
|
+
return -1;
|
|
279
|
+
if (!collA && collB)
|
|
280
|
+
return 1;
|
|
281
|
+
let ret = (collA || '').localeCompare(collB || '');
|
|
282
|
+
if (ret === 0) {
|
|
283
|
+
ret = (a.getName() || '').localeCompare(b.getName() || '');
|
|
284
|
+
}
|
|
285
|
+
return ret;
|
|
286
|
+
});
|
|
287
|
+
const matrix = [['Book Id', 'Name', 'Owner', 'Collection']];
|
|
288
|
+
for (const book of books) {
|
|
289
|
+
matrix.push([
|
|
290
|
+
book.getId() || '',
|
|
291
|
+
book.getName() || '',
|
|
292
|
+
book.getOwnerName() || '',
|
|
293
|
+
((_a = book.getCollection()) === null || _a === void 0 ? void 0 : _a.getName()) || '',
|
|
294
|
+
]);
|
|
295
|
+
}
|
|
266
296
|
renderTable(matrix, false);
|
|
267
297
|
}
|
|
268
298
|
}
|
|
@@ -288,7 +318,7 @@ bookCommand
|
|
|
288
318
|
bookCommand
|
|
289
319
|
.command('create')
|
|
290
320
|
.description('Create a new book')
|
|
291
|
-
.
|
|
321
|
+
.option('--name <name>', 'Book name')
|
|
292
322
|
.option('--fraction-digits <digits>', 'Number of decimal places (0-8)', parseInt)
|
|
293
323
|
.option('--date-pattern <pattern>', 'Date format pattern (dd/MM/yyyy, MM/dd/yyyy, or yyyy/MM/dd)')
|
|
294
324
|
.option('--decimal-separator <separator>', 'Decimal separator (DOT or COMMA)')
|
|
@@ -297,6 +327,7 @@ bookCommand
|
|
|
297
327
|
.option('-p, --property <key=value>', 'Set a property (repeatable)', collectProperty)
|
|
298
328
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
299
329
|
try {
|
|
330
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'name', flag: '--name' }]));
|
|
300
331
|
setupBkper();
|
|
301
332
|
const book = yield createBook({
|
|
302
333
|
name: options.name,
|
|
@@ -352,9 +383,10 @@ const accountCommand = program.command('account').description('Manage Accounts')
|
|
|
352
383
|
accountCommand
|
|
353
384
|
.command('list')
|
|
354
385
|
.description('List all accounts in a book')
|
|
355
|
-
.
|
|
386
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
356
387
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
357
388
|
try {
|
|
389
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
358
390
|
setupBkper();
|
|
359
391
|
const bookId = options.book;
|
|
360
392
|
const accounts = yield listAccounts(bookId);
|
|
@@ -377,9 +409,10 @@ accountCommand
|
|
|
377
409
|
accountCommand
|
|
378
410
|
.command('get <idOrName>')
|
|
379
411
|
.description('Get an account by ID or name')
|
|
380
|
-
.
|
|
412
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
381
413
|
.action((idOrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
382
414
|
try {
|
|
415
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
383
416
|
setupBkper();
|
|
384
417
|
const bookId = options.book;
|
|
385
418
|
const account = yield getAccount(bookId, idOrName);
|
|
@@ -393,14 +426,18 @@ accountCommand
|
|
|
393
426
|
accountCommand
|
|
394
427
|
.command('create')
|
|
395
428
|
.description('Create a new account')
|
|
396
|
-
.
|
|
397
|
-
.
|
|
429
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
430
|
+
.option('--name <name>', 'Account name')
|
|
398
431
|
.option('--type <type>', 'Account type (ASSET, LIABILITY, INCOMING, OUTGOING)')
|
|
399
432
|
.option('--description <description>', 'Account description')
|
|
400
433
|
.option('--groups <groups>', 'Comma-separated group names')
|
|
401
434
|
.option('-p, --property <key=value>', 'Set a property (repeatable)', collectProperty)
|
|
402
435
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
403
436
|
try {
|
|
437
|
+
throwIfErrors(validateRequiredOptions(options, [
|
|
438
|
+
{ name: 'book', flag: '--book' },
|
|
439
|
+
{ name: 'name', flag: '--name' },
|
|
440
|
+
]));
|
|
404
441
|
setupBkper();
|
|
405
442
|
const bookId = options.book;
|
|
406
443
|
const account = yield createAccount(bookId, {
|
|
@@ -422,13 +459,14 @@ accountCommand
|
|
|
422
459
|
accountCommand
|
|
423
460
|
.command('update <idOrName>')
|
|
424
461
|
.description('Update an account')
|
|
425
|
-
.
|
|
462
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
426
463
|
.option('--name <name>', 'Account name')
|
|
427
464
|
.option('--type <type>', 'Account type (ASSET, LIABILITY, INCOMING, OUTGOING)')
|
|
428
465
|
.option('--archived <archived>', 'Archive status (true/false)')
|
|
429
466
|
.option('-p, --property <key=value>', 'Set a property (repeatable)', collectProperty)
|
|
430
467
|
.action((idOrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
431
468
|
try {
|
|
469
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
432
470
|
setupBkper();
|
|
433
471
|
const bookId = options.book;
|
|
434
472
|
const account = yield updateAccount(bookId, idOrName, {
|
|
@@ -447,9 +485,10 @@ accountCommand
|
|
|
447
485
|
accountCommand
|
|
448
486
|
.command('delete <idOrName>')
|
|
449
487
|
.description('Delete an account')
|
|
450
|
-
.
|
|
488
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
451
489
|
.action((idOrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
452
490
|
try {
|
|
491
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
453
492
|
setupBkper();
|
|
454
493
|
const bookId = options.book;
|
|
455
494
|
const account = yield deleteAccount(bookId, idOrName);
|
|
@@ -465,9 +504,10 @@ const groupCommand = program.command('group').description('Manage Groups');
|
|
|
465
504
|
groupCommand
|
|
466
505
|
.command('list')
|
|
467
506
|
.description('List all groups in a book')
|
|
468
|
-
.
|
|
507
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
469
508
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
470
509
|
try {
|
|
510
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
471
511
|
setupBkper();
|
|
472
512
|
const bookId = options.book;
|
|
473
513
|
const groups = yield listGroups(bookId);
|
|
@@ -487,9 +527,10 @@ groupCommand
|
|
|
487
527
|
groupCommand
|
|
488
528
|
.command('get <idOrName>')
|
|
489
529
|
.description('Get a group by ID or name')
|
|
490
|
-
.
|
|
530
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
491
531
|
.action((idOrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
492
532
|
try {
|
|
533
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
493
534
|
setupBkper();
|
|
494
535
|
const bookId = options.book;
|
|
495
536
|
const group = yield getGroup(bookId, idOrName);
|
|
@@ -503,13 +544,17 @@ groupCommand
|
|
|
503
544
|
groupCommand
|
|
504
545
|
.command('create')
|
|
505
546
|
.description('Create a new group')
|
|
506
|
-
.
|
|
507
|
-
.
|
|
547
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
548
|
+
.option('--name <name>', 'Group name')
|
|
508
549
|
.option('--parent <parent>', 'Parent group name or ID')
|
|
509
550
|
.option('--hidden', 'Hide the group')
|
|
510
551
|
.option('-p, --property <key=value>', 'Set a property (repeatable)', collectProperty)
|
|
511
552
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
512
553
|
try {
|
|
554
|
+
throwIfErrors(validateRequiredOptions(options, [
|
|
555
|
+
{ name: 'book', flag: '--book' },
|
|
556
|
+
{ name: 'name', flag: '--name' },
|
|
557
|
+
]));
|
|
513
558
|
setupBkper();
|
|
514
559
|
const bookId = options.book;
|
|
515
560
|
const group = yield createGroup(bookId, {
|
|
@@ -528,12 +573,13 @@ groupCommand
|
|
|
528
573
|
groupCommand
|
|
529
574
|
.command('update <idOrName>')
|
|
530
575
|
.description('Update a group')
|
|
531
|
-
.
|
|
576
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
532
577
|
.option('--name <name>', 'Group name')
|
|
533
578
|
.option('--hidden <hidden>', 'Hide status (true/false)')
|
|
534
579
|
.option('-p, --property <key=value>', 'Set a property (repeatable)', collectProperty)
|
|
535
580
|
.action((idOrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
536
581
|
try {
|
|
582
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
537
583
|
setupBkper();
|
|
538
584
|
const bookId = options.book;
|
|
539
585
|
const group = yield updateGroup(bookId, idOrName, {
|
|
@@ -551,9 +597,10 @@ groupCommand
|
|
|
551
597
|
groupCommand
|
|
552
598
|
.command('delete <idOrName>')
|
|
553
599
|
.description('Delete a group')
|
|
554
|
-
.
|
|
600
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
555
601
|
.action((idOrName, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
556
602
|
try {
|
|
603
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
557
604
|
setupBkper();
|
|
558
605
|
const bookId = options.book;
|
|
559
606
|
const group = yield deleteGroup(bookId, idOrName);
|
|
@@ -569,13 +616,17 @@ const transactionCommand = program.command('transaction').description('Manage Tr
|
|
|
569
616
|
transactionCommand
|
|
570
617
|
.command('list')
|
|
571
618
|
.description('List transactions in a book')
|
|
572
|
-
.
|
|
573
|
-
.
|
|
619
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
620
|
+
.option('-q, --query <query>', 'Search query')
|
|
574
621
|
.option('-l, --limit <limit>', 'Maximum number of results (1-1000)', parseInt)
|
|
575
622
|
.option('-c, --cursor <cursor>', 'Pagination cursor')
|
|
576
623
|
.option('-p, --properties', 'Include custom properties')
|
|
577
624
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
578
625
|
try {
|
|
626
|
+
throwIfErrors(validateRequiredOptions(options, [
|
|
627
|
+
{ name: 'book', flag: '--book' },
|
|
628
|
+
{ name: 'query', flag: '--query' },
|
|
629
|
+
]));
|
|
579
630
|
setupBkper();
|
|
580
631
|
const bookId = options.book;
|
|
581
632
|
const result = yield listTransactions(bookId, {
|
|
@@ -614,9 +665,9 @@ transactionCommand
|
|
|
614
665
|
transactionCommand
|
|
615
666
|
.command('create')
|
|
616
667
|
.description('Create a transaction')
|
|
617
|
-
.
|
|
618
|
-
.
|
|
619
|
-
.
|
|
668
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
669
|
+
.option('--date <date>', 'Transaction date')
|
|
670
|
+
.option('--amount <amount>', 'Transaction amount')
|
|
620
671
|
.option('--description <description>', 'Transaction description')
|
|
621
672
|
.option('--from <from>', 'Credit account (source)')
|
|
622
673
|
.option('--to <to>', 'Debit account (destination)')
|
|
@@ -625,6 +676,11 @@ transactionCommand
|
|
|
625
676
|
.option('-p, --property <key=value>', 'Set a property (repeatable, empty value deletes)', collectProperty)
|
|
626
677
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
627
678
|
try {
|
|
679
|
+
throwIfErrors(validateRequiredOptions(options, [
|
|
680
|
+
{ name: 'book', flag: '--book' },
|
|
681
|
+
{ name: 'date', flag: '--date' },
|
|
682
|
+
{ name: 'amount', flag: '--amount' },
|
|
683
|
+
]));
|
|
628
684
|
setupBkper();
|
|
629
685
|
const bookId = options.book;
|
|
630
686
|
const transaction = yield createTransaction(bookId, {
|
|
@@ -647,9 +703,10 @@ transactionCommand
|
|
|
647
703
|
transactionCommand
|
|
648
704
|
.command('post <transactionId>')
|
|
649
705
|
.description('Post a transaction')
|
|
650
|
-
.
|
|
706
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
651
707
|
.action((transactionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
652
708
|
try {
|
|
709
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
653
710
|
setupBkper();
|
|
654
711
|
const bookId = options.book;
|
|
655
712
|
const transaction = yield postTransaction(bookId, transactionId);
|
|
@@ -663,7 +720,7 @@ transactionCommand
|
|
|
663
720
|
transactionCommand
|
|
664
721
|
.command('update <transactionId>')
|
|
665
722
|
.description('Update a transaction')
|
|
666
|
-
.
|
|
723
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
667
724
|
.option('--date <date>', 'Transaction date')
|
|
668
725
|
.option('--amount <amount>', 'Transaction amount')
|
|
669
726
|
.option('--description <description>', 'Transaction description')
|
|
@@ -673,6 +730,7 @@ transactionCommand
|
|
|
673
730
|
.option('-p, --property <key=value>', 'Set a property (repeatable, empty value deletes)', collectProperty)
|
|
674
731
|
.action((transactionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
675
732
|
try {
|
|
733
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
676
734
|
setupBkper();
|
|
677
735
|
const bookId = options.book;
|
|
678
736
|
const transaction = yield updateTransaction(bookId, transactionId, {
|
|
@@ -694,9 +752,10 @@ transactionCommand
|
|
|
694
752
|
transactionCommand
|
|
695
753
|
.command('check <transactionId>')
|
|
696
754
|
.description('Check a transaction')
|
|
697
|
-
.
|
|
755
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
698
756
|
.action((transactionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
699
757
|
try {
|
|
758
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
700
759
|
setupBkper();
|
|
701
760
|
const bookId = options.book;
|
|
702
761
|
const transaction = yield checkTransaction(bookId, transactionId);
|
|
@@ -710,9 +769,10 @@ transactionCommand
|
|
|
710
769
|
transactionCommand
|
|
711
770
|
.command('trash <transactionId>')
|
|
712
771
|
.description('Trash a transaction')
|
|
713
|
-
.
|
|
772
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
714
773
|
.action((transactionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
715
774
|
try {
|
|
775
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
716
776
|
setupBkper();
|
|
717
777
|
const bookId = options.book;
|
|
718
778
|
const transaction = yield trashTransaction(bookId, transactionId);
|
|
@@ -726,9 +786,10 @@ transactionCommand
|
|
|
726
786
|
transactionCommand
|
|
727
787
|
.command('merge <transactionId1> <transactionId2>')
|
|
728
788
|
.description('Merge two transactions')
|
|
729
|
-
.
|
|
789
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
730
790
|
.action((transactionId1, transactionId2, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
731
791
|
try {
|
|
792
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
732
793
|
setupBkper();
|
|
733
794
|
const bookId = options.book;
|
|
734
795
|
const result = yield mergeTransactions(bookId, transactionId1, transactionId2);
|
|
@@ -753,11 +814,15 @@ const balanceCommand = program.command('balance').description('Manage Balances')
|
|
|
753
814
|
balanceCommand
|
|
754
815
|
.command('list')
|
|
755
816
|
.description('List balances')
|
|
756
|
-
.
|
|
757
|
-
.
|
|
817
|
+
.option('-b, --book <bookId>', 'Book ID')
|
|
818
|
+
.option('-q, --query <query>', 'Balances query')
|
|
758
819
|
.option('--expanded <level>', 'Expand groups to specified depth (0+)', parseInt)
|
|
759
820
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
760
821
|
try {
|
|
822
|
+
throwIfErrors(validateRequiredOptions(options, [
|
|
823
|
+
{ name: 'book', flag: '--book' },
|
|
824
|
+
{ name: 'query', flag: '--query' },
|
|
825
|
+
]));
|
|
761
826
|
setupBkper();
|
|
762
827
|
const bookId = options.book;
|
|
763
828
|
const matrix = yield listBalancesMatrix(bookId, {
|
|
@@ -818,9 +883,10 @@ collectionCommand
|
|
|
818
883
|
collectionCommand
|
|
819
884
|
.command('create')
|
|
820
885
|
.description('Create a new collection')
|
|
821
|
-
.
|
|
886
|
+
.option('--name <name>', 'Collection name')
|
|
822
887
|
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
823
888
|
try {
|
|
889
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'name', flag: '--name' }]));
|
|
824
890
|
setupBkper();
|
|
825
891
|
const collection = yield createCollection({ name: options.name });
|
|
826
892
|
renderItem(collection.json(), isJson());
|
|
@@ -867,9 +933,10 @@ function collectBook(value, previous) {
|
|
|
867
933
|
collectionCommand
|
|
868
934
|
.command('add-book <collectionId>')
|
|
869
935
|
.description('Add books to a collection')
|
|
870
|
-
.
|
|
936
|
+
.option('-b, --book <bookId>', 'Book ID (repeatable)', collectBook)
|
|
871
937
|
.action((collectionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
872
938
|
try {
|
|
939
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
873
940
|
setupBkper();
|
|
874
941
|
const books = yield addBookToCollection(collectionId, options.book);
|
|
875
942
|
if (isJson()) {
|
|
@@ -887,9 +954,10 @@ collectionCommand
|
|
|
887
954
|
collectionCommand
|
|
888
955
|
.command('remove-book <collectionId>')
|
|
889
956
|
.description('Remove books from a collection')
|
|
890
|
-
.
|
|
957
|
+
.option('-b, --book <bookId>', 'Book ID (repeatable)', collectBook)
|
|
891
958
|
.action((collectionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
892
959
|
try {
|
|
960
|
+
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
893
961
|
setupBkper();
|
|
894
962
|
const books = yield removeBookFromCollection(collectionId, options.book);
|
|
895
963
|
if (isJson()) {
|