bkper-js 2.32.0 → 2.32.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/lib/index.d.ts CHANGED
@@ -1836,6 +1836,7 @@ export declare class Book extends ResourceProperty<bkper.Book> {
1836
1836
  * @returns The created Accounts
1837
1837
  */
1838
1838
  batchCreateAccounts(accounts: Account[]): Promise<Account[]>;
1839
+
1839
1840
  /**
1840
1841
  * Update [[Accounts]] on the Book, in batch.
1841
1842
  *
package/lib/model/Book.js CHANGED
@@ -567,7 +567,7 @@ export class Book extends ResourceProperty {
567
567
  return __awaiter(this, void 0, void 0, function* () {
568
568
  if (accounts.length > 0) {
569
569
  const accountList = {
570
- items: accounts.map(a => a.json()),
570
+ items: yield Promise.all(accounts.map(account => this.normalizeAccountPayloadForBatchCreate_(account))),
571
571
  };
572
572
  const payloads = yield AccountService.createAccounts(this.getId(), accountList, this.getConfig());
573
573
  const createdAccounts = [];
@@ -582,6 +582,29 @@ export class Book extends ResourceProperty {
582
582
  return [];
583
583
  });
584
584
  }
585
+ /** @internal */
586
+ normalizeAccountPayloadForBatchCreate_(account) {
587
+ return __awaiter(this, void 0, void 0, function* () {
588
+ const payload = account.json();
589
+ if (!payload.groups || payload.groups.length === 0) {
590
+ return payload;
591
+ }
592
+ const normalizedGroups = [];
593
+ for (const groupPayload of payload.groups) {
594
+ const idOrName = groupPayload.id || groupPayload.name;
595
+ if (!idOrName || idOrName.trim() === '') {
596
+ throw new Error('Account group reference must include id or name');
597
+ }
598
+ const group = yield this.getGroup(idOrName);
599
+ if (!group) {
600
+ throw new Error(`Group not found: ${idOrName}`);
601
+ }
602
+ normalizedGroups.push(group.json());
603
+ }
604
+ payload.groups = normalizedGroups;
605
+ return payload;
606
+ });
607
+ }
585
608
  /**
586
609
  * Update [[Accounts]] on the Book, in batch.
587
610
  *
@@ -28,6 +28,7 @@ export class HttpApiRequest extends HttpRequest {
28
28
  super(`${baseUrl}/${path}`);
29
29
  this.retry = 0;
30
30
  this.config = config;
31
+ this.requestPath = path;
31
32
  }
32
33
  fetch() {
33
34
  const _super = Object.create(null, {
@@ -52,14 +53,14 @@ export class HttpApiRequest extends HttpRequest {
52
53
  };
53
54
  throw this.handleError(errorObj);
54
55
  }
55
- else if (resp.status != 400 && this.retry <= 3) {
56
+ else if (this.shouldRetry(resp.status) && this.retry < 3) {
56
57
  this.retry++;
57
58
  const effectiveConfig = this.config;
58
59
  if (effectiveConfig.requestRetryHandler) {
59
60
  yield effectiveConfig.requestRetryHandler(resp.status, resp.data, this.retry);
60
61
  }
61
62
  else {
62
- console.log(`${JSON.stringify(resp.data)} - Retrying... `);
63
+ console.log(`${JSON.stringify(resp.data)} - Retrying ${this.retry}/3... `);
63
64
  }
64
65
  return yield this.fetch();
65
66
  }
@@ -75,21 +76,24 @@ export class HttpApiRequest extends HttpRequest {
75
76
  }
76
77
  }
77
78
  catch (error) {
78
- // If error already has response structure (from our code above), use it
79
+ if (error instanceof BkperError) {
80
+ throw error;
81
+ }
82
+ // If error already has response structure (from upstream), preserve it
79
83
  if (error.response) {
80
84
  throw error;
81
85
  }
82
86
  // Network error or fetch failure
83
- if (error instanceof TypeError && error.message.includes("fetch")) {
87
+ if (this.isNetworkError(error)) {
84
88
  // Network error - retry if within retry limit
85
- if (this.retry <= 3) {
89
+ if (this.retry < 3) {
86
90
  this.retry++;
87
91
  const effectiveConfig = this.config;
88
92
  if (effectiveConfig.requestRetryHandler) {
89
- yield effectiveConfig.requestRetryHandler(520, undefined, this.retry);
93
+ yield effectiveConfig.requestRetryHandler(520, error, this.retry);
90
94
  }
91
95
  else {
92
- console.log(`Network error - Retrying... `);
96
+ console.log(`${this.formatNetworkErrorMessage(error)} - Retrying ${this.retry}/3... `);
93
97
  }
94
98
  return yield this.fetch();
95
99
  }
@@ -98,8 +102,37 @@ export class HttpApiRequest extends HttpRequest {
98
102
  }
99
103
  });
100
104
  }
105
+ shouldRetry(status) {
106
+ return status == 408 || status == 429 || (status != null && status >= 500);
107
+ }
108
+ isNetworkError(error) {
109
+ return error instanceof TypeError && error.message.toLowerCase().includes("fetch");
110
+ }
111
+ formatNetworkErrorMessage(error) {
112
+ var _a, _b, _c, _d, _e;
113
+ const details = [];
114
+ if ((_a = error.cause) === null || _a === void 0 ? void 0 : _a.code) {
115
+ details.push(error.cause.code);
116
+ }
117
+ if ((_b = error.cause) === null || _b === void 0 ? void 0 : _b.hostname) {
118
+ details.push(error.cause.hostname);
119
+ }
120
+ else if ((_c = error.cause) === null || _c === void 0 ? void 0 : _c.address) {
121
+ details.push(error.cause.address);
122
+ }
123
+ if (((_d = error.cause) === null || _d === void 0 ? void 0 : _d.port) !== undefined) {
124
+ details.push(`port=${error.cause.port}`);
125
+ }
126
+ if ((_e = error.cause) === null || _e === void 0 ? void 0 : _e.syscall) {
127
+ details.push(`syscall=${error.cause.syscall}`);
128
+ }
129
+ if (details.length > 0) {
130
+ return `Network error calling ${this.requestPath}: ${error.message} (${details.join(", ")})`;
131
+ }
132
+ return `Network error calling ${this.requestPath}: ${error.message}`;
133
+ }
101
134
  handleError(err) {
102
- var _a, _b, _c, _d, _e, _f, _g;
135
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
103
136
  const effectiveConfig = this.config;
104
137
  const customError = effectiveConfig.requestErrorHandler
105
138
  ? effectiveConfig.requestErrorHandler(err)
@@ -107,16 +140,22 @@ export class HttpApiRequest extends HttpRequest {
107
140
  if (customError) {
108
141
  return customError;
109
142
  }
143
+ else if (err instanceof BkperError) {
144
+ return err;
145
+ }
146
+ else if (this.isNetworkError(err)) {
147
+ return new BkperError(((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) || ((_b = err.response) === null || _b === void 0 ? void 0 : _b.code) || err.status || err.code || 0, this.formatNetworkErrorMessage(err), undefined);
148
+ }
110
149
  else {
111
150
  // Read internal HttpError from response
112
- let error = ((_b = (_a = err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) || ((_c = err.data) === null || _c === void 0 ? void 0 : _c.error) || err.error;
151
+ let error = ((_d = (_c = err.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.error) || ((_e = err.data) === null || _e === void 0 ? void 0 : _e.error) || err.error;
113
152
  if (error) {
114
153
  // Transform to BkperError
115
- return new BkperError(error.code, error.message, (_e = (_d = error.errors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.reason);
154
+ return new BkperError(error.code, error.message, (_g = (_f = error.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.reason);
116
155
  }
117
156
  else {
118
157
  // Fallback for network errors, etc.
119
- return new BkperError(((_f = err.response) === null || _f === void 0 ? void 0 : _f.status) || ((_g = err.response) === null || _g === void 0 ? void 0 : _g.code) || err.status || err.code || 0, err.message || String(err), undefined);
158
+ return new BkperError(((_h = err.response) === null || _h === void 0 ? void 0 : _h.status) || ((_j = err.response) === null || _j === void 0 ? void 0 : _j.code) || err.status || err.code || 0, err.message || String(err), undefined);
120
159
  }
121
160
  }
122
161
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bkper-js",
3
- "version": "2.32.0",
3
+ "version": "2.32.2",
4
4
  "description": "Javascript client for Bkper REST API",
5
5
  "main": "./lib/index.js",
6
6
  "module": "./lib/index.js",
@@ -18,7 +18,8 @@
18
18
  "license": "Apache-2.0",
19
19
  "private": false,
20
20
  "scripts": {
21
- "test": "env TS_NODE_COMPILER_OPTIONS='{\"rootDir\": \".\", \"lib\": [\"es2020\", \"dom\"] }' mocha -r ts-node/register 'test/**/*.ts'",
21
+ "test": "env TS_NODE_COMPILER_OPTIONS='{\"rootDir\": \".\", \"lib\": [\"es2020\", \"dom\"] }' mocha -r ts-node/register 'test/**/*.ts' --ignore 'test/integration/**/*.ts'",
22
+ "test:integration": "env TS_NODE_COMPILER_OPTIONS='{\"rootDir\": \".\", \"lib\": [\"es2020\", \"dom\"] }' mocha --config .mocharc.integration.json",
22
23
  "clean": "rm -rf ./lib & rm -rf ./node_modules & wait",
23
24
  "prebuild": "bun install",
24
25
  "build": "run-s build:*",
@@ -31,12 +32,7 @@
31
32
  "build:clean-dist": "rimraf dist",
32
33
  "build:bundle": "esbuild lib/index.js --bundle --format=iife --global-name=bkperjs --minify --sourcemap --target=es2015 --platform=browser --outfile=dist/bkper.min.js",
33
34
  "dev": "tsc -w",
34
- "upgrade:api": "bun update @bkper/bkper-api-types --latest",
35
- "patch": "yarn version --patch",
36
- "minor": "yarn version --minor",
37
- "major": "yarn version --major",
38
- "preversion": "bun run build",
39
- "postversion": "git push --tags && yarn publish --new-version $npm_package_version && git push && echo \"Successfully released version $npm_package_version!\""
35
+ "upgrade:api": "bun update @bkper/bkper-api-types --latest"
40
36
  },
41
37
  "dependencies": {
42
38
  "@bkper/bkper-api-types": "^5.39.1",
@@ -54,6 +50,7 @@
54
50
  "@types/node": "^14.14.20",
55
51
  "@types/node-fetch": "^2.5.8",
56
52
  "@types/uuid": "^10.0.0",
53
+ "bkper": "^4.12.0",
57
54
  "chai": "^5.1.1",
58
55
  "esbuild": "^0.27.4",
59
56
  "gts": "^3.0.3",
package/CHANGELOG.md DELETED
@@ -1,464 +0,0 @@
1
- ### **Changelog**
2
-
3
- See what's new and what has changed in bkper-js
4
-
5
- ## 2026
6
-
7
- **March 2026**
8
-
9
- - Added `Book.batchUpdateAccounts`
10
- - Added `Book.batchDeleteAccounts`
11
-
12
- **February 2026**
13
-
14
- - Added `User.getGivenName`
15
- - Added `BooksDataTableBuilder`
16
- - Added `AccountsDataTableBuilder`
17
- - Added `GroupsDataTableBuilder`
18
- - Added `TransactionsDataTableBuilder`
19
- - Added `Book.createAccountsDataTable`
20
- - Added `Book.createGroupsDataTable`
21
- - Added `Book.createTransactionsDataTable`
22
- - Added `TransactionsDataTableBuilder.ids`
23
- - Added `TransactionsDataTableBuilder.properties`
24
- - Added `TransactionsDataTableBuilder.urls`
25
- - Added `TransactionsDataTableBuilder.recordedAt`
26
- - Added `AccountsDataTableBuilder.hiddenProperties`
27
- - Added `BooksDataTableBuilder.hiddenProperties`
28
- - Added `GroupsDataTableBuilder.hiddenProperties`
29
- - Added `GroupsDataTableBuilder.tree`
30
- - Added `TransactionsDataTableBuilder.hiddenProperties`
31
- - Added `BalancesDataTableBuilder.hiddenProperties`
32
-
33
-
34
- **January 2026**
35
-
36
- - Added `App.setUsers`
37
- - Added `App.getUsers`
38
- - Added `App.setDevelopers`
39
- - Added `App.getDevelopers`
40
- - Added `Config.agentIdProvider`
41
- - Added `Billing`
42
- - Added `Billing.getAdminEmail`
43
- - Added `Billing.getCheckoutUrl`
44
- - Added `Billing.getCounts`
45
- - Added `Billing.getDaysLeftInTrial`
46
- - Added `Billing.getEmail`
47
- - Added `Billing.getHostedDomain`
48
- - Added `Billing.getPlan`
49
- - Added `Billing.getPortalUrl`
50
- - Added `Billing.getTotalTransactionsThisMonth`
51
- - Added `Billing.getTotalTransactionsThisYear`
52
- - Added `Billing.hasStartedTrial`
53
- - Added `Billing.isEnabled`
54
- - Added `Billing.isPlanOverdue`
55
- - Added `User.getBilling`
56
- - Added `User.getUsername`
57
- - Removed `App.setUserEmails` from `App`. Use `App.setUsers` instead
58
- - Removed `App.setDeveloperEmail` from `App`. Use `App.setDevelopers` instead
59
- - Removed `Bkper.getBillingPortalUrl` from `Bkper`. Use `Billing.getPortalUrl` instead
60
- - Removed `User.getDaysLeftInTrial` from `User`. Use `Billing.getDaysLeftInTrial` instead
61
- - Removed `User.getPlan` from `User`. Use `Billing.getPlan` instead
62
- - Removed `User.hasBillingEnabled` from `User`. Use `Billing.isEnabled` instead
63
- - Removed `User.hasStartedTrial` from `User`. Use `Billing.hasStartedTrial` instead
64
- - Removed `User.isFree` from `User`. Use `Billing.getPlan` instead
65
-
66
- ## 2025
67
-
68
- **December 2025**
69
-
70
- - Added `File.update`
71
- - Added `EventType.FILE_UPDATED`
72
-
73
- **November 2025**
74
-
75
- - **v2.15.2 - INTERNAL REFACTOR:**
76
- - Introduced `ResourceProperty` abstract class for model entities that support custom properties
77
- - Moved shared property methods to ResourceProperty
78
- - Refactor 7 model classes to extend ResourceProperty instead of Resource
79
- - Eliminate ~350 lines of duplicated property management code
80
- - Maintained full backward compatibility - no breaking changes to existing APIs
81
- - Added `ResourceProperty.setVisibleProperty`
82
- - Added `ResourceProperty.setVisibleProperties`
83
- - Added `ResourceProperty.getVisibleProperties`
84
- - Added `Bkper.getConfig`
85
-
86
- **October 2025**
87
-
88
- - Files attached to transactions are now created internally when transaction is persisted
89
- - Added `Transaction.removeFile`
90
- - Added `Book.countTransactions`
91
- - Added `Book.remove`
92
-
93
- **September 2025**
94
-
95
- - **v2.8.0 - INTERNAL REFACTOR:**
96
- - Introduced abstract `Resource` class for all model entities
97
- - Improved config management with `getConfig()` pattern for config resolution
98
- - Enhanced type safety with explicit Config type usage throughout
99
- - Standardized `json()` method across resources for consistent JSON serialization
100
- - Maintained full backward compatibility - no breaking changes to existing APIs
101
- - Added `Account.isBalanceVerified`
102
- - Added `App.getOwnerWebsiteUrl`
103
- - Added `App.getReadme`
104
- - Added `App.getRepositoryUrl`
105
- - Added `App.getWebsiteUrl`
106
- - Added `App.isInstallable`
107
- - Added `App.isRepositoryPrivate`
108
- - Added `Book.getCollaborators`
109
- - Added `Book.getBacklog`
110
- - Added `Backlog`
111
- - Added `Backlog.getCount`
112
- - Added `Collaborator`
113
- - Added `Collaborator.json`
114
- - Added `Collaborator.getId`
115
- - Added `Collaborator.getEmail`
116
- - Added `Collaborator.getPermission`
117
- - Added `Collaborator.setEmail`
118
- - Added `Collaborator.setPermission`
119
- - Added `Collaborator.create`
120
- - Added `Collaborator.update`
121
- - Added `Collaborator.remove`
122
- - Added `Group.isBalanceVerified`
123
- - Deprecated `Integration.getLogo`
124
- - Added `Integration.getLogoUrl`
125
- - Added `Integration.getLogoUrlDark`
126
- - Added `Transaction.getCreatedBy`
127
- - Replaced axios with native Fetch API for better compatibility with multiple environments
128
-
129
- **August 2025**
130
-
131
- - Added `File.getProperties`
132
- - Added `File.setProperties`
133
- - Added `File.getProperty`
134
- - Added `File.setProperty`
135
- - Added `File.deleteProperty`
136
-
137
- **July 2025**
138
-
139
- - **BREAKING CHANGE:** Refactored `Bkper` class from static methods to constructor-based pattern
140
- - **BREAKING CHANGE:** Removed deprecated methods: `Transaction.remove()`, `Transaction.restore()`, `Account.getBalance()`, `Account.getBalanceRaw()`
141
- - **MIGRATION:** Use `transaction.trash()` and `transaction.untrash()` instead of `remove()` and `restore()`
142
- - **MIGRATION:** Use `Book.getBalancesReport()` instead of `Account.getBalance()` methods
143
- - Added `Balance` class back for improved balance reporting
144
- - Added `BalancesDataTableBuilder` for building balance data tables
145
- - Added `BalanceType` enum with TOTAL, PERIOD, and CUMULATIVE options
146
- - Added `includeGroups` parameter to `Bkper.getBook()` method for selective group loading
147
-
148
- **June 2025**
149
-
150
- - Added `Book.copy`
151
- - Added `Transaction.getUpdatedAt`
152
- - Added `Transaction.getUpdatedAtFormatted`
153
-
154
- **May 2025**
155
-
156
- - Added `Group.isLocked`
157
- - Added `Group.setLocked`
158
- - Added `Query`
159
- - Added `Query.json`
160
- - Added `Query.getId`
161
- - Added `Query.getTitle`
162
- - Added `Query.setTitle`
163
- - Added `Query.getQuery`
164
- - Added `Query.setQuery`
165
- - Added `Query.create`
166
- - Added `Query.update`
167
- - Added `Query.remove`
168
- - Added `Book.getSavedQueries`
169
- - Added `Book.batchPostTransactions`
170
- - Added `Book.batchCheckTransactions`
171
- - Added `Book.batchUncheckTransactions`
172
- - Added `Book.batchUpdateTransactions`
173
- - Added `Book.batchUntrashTransactions`
174
-
175
- **April 2025**
176
-
177
- - Added `Book.batchCreateAccounts`
178
- - Added `Book.batchCreateGroups`
179
-
180
- **March 2025**
181
-
182
- - Added `Agent.getLogoUrlDark`
183
- - Added `App.getFilePatterns`
184
- - Added `App.getLogoUrlDark`
185
- - Added `App.getOwnerLogoUrl`
186
- - Added `App.getOwnerName`
187
- - Added `App.isPublished`
188
- - Added `Transaction.getAgentName`
189
- - Added `Transaction.getAgentLogoUrl`
190
- - Added `Transaction.getAgentLogoUrlDark`
191
-
192
- **February 2025**
193
-
194
- - Added `EventType` enum
195
- - Added `BotResponseType` enum
196
- - Added `Agent`
197
- - Added `Agent.getId`
198
- - Added `Agent.getLogoUrl`
199
- - Added `Agent.getName`
200
- - Added `Agent.json`
201
- - Added `App.getDescription`
202
- - Added `App.getEvents`
203
- - Added `App.getLogoUrl`
204
- - Added `App.getName`
205
- - Added `App.hasEvents`
206
- - Added `Book.batchReplayEvents`
207
- - Added `Book.getApps`
208
- - Added `BotResponse`
209
- - Added `BotResponse.getAgentId`
210
- - Added `BotResponse.getCreatedAt`
211
- - Added `BotResponse.getEvent`
212
- - Added `BotResponse.getMessage`
213
- - Added `BotResponse.getType`
214
- - Added `BotResponse.remove`
215
- - Added `BotResponse.replay`
216
- - Added `Event.getAgent`
217
- - Added `Event.getBook`
218
- - Added `Event.getBotResponses`
219
- - Added `Event.getCreatedAt`
220
- - Added `Event.getId`
221
- - Added `Event.getType`
222
- - Added `Event.getUser`
223
- - Added `Event.hasErrorResponse`
224
- - Added `User.getAvatarUrl`
225
-
226
- **January 2025**
227
-
228
- - Added `BalancesContainer`
229
- - Added `BalancesContainer.getName`
230
- - Added `BalancesContainer.getNormalizedName`
231
- - Added `BalancesContainer.getGroup`
232
- - Added `BalancesContainer.getAccount`
233
- - Added `BalancesContainer.getParent`
234
- - Added `BalancesContainer.getDepth`
235
- - Added `BalancesContainer.isCredit`
236
- - Added `BalancesContainer.isPermanent`
237
- - Added `BalancesContainer.isFromAccount`
238
- - Added `BalancesContainer.isFromGroup`
239
- - Added `BalancesContainer.hasGroupBalances`
240
- - Added `BalancesContainer.getCumulativeBalance`
241
- - Added `BalancesContainer.getCumulativeBalanceRaw`
242
- - Added `BalancesContainer.getCumulativeBalanceText`
243
- - Added `BalancesContainer.getCumulativeBalanceRawText`
244
- - Added `BalancesContainer.getPeriodBalance`
245
- - Added `BalancesContainer.getPeriodBalanceRaw`
246
- - Added `BalancesContainer.getPeriodBalanceText`
247
- - Added `BalancesContainer.getPeriodBalanceRawText`
248
- - Added `BalancesContainer.getBalancesContainers`
249
- - Added `BalancesContainer.getBalancesContainer`
250
- - Added `BalancesReport`
251
- - Added `BalancesReport.getBook`
252
- - Added `BalancesReport.getPeriod`
253
- - Added `BalancesReport.getBalancesContainers`
254
- - Added `BalancesReport.getBalancesContainer`
255
- - Added `Book.getAutoPost`
256
- - Added `Book.setAutoPost`
257
- - Added `Group.isCredit`
258
- - Added `Group.isMixed`
259
- - Added `User.getPlan`
260
- - Added `User.hasBillingEnabled`
261
-
262
- ## 2024
263
-
264
- **December 2024**
265
-
266
- - Added `Book.listEvents`
267
- - Added `EventList`
268
- - Added `EventList.getCursor`
269
- - Added `EventList.getFirst`
270
- - Added `EventList.getItems`
271
- - Added `EventList.size`
272
- - Added `Group.isPermanent`
273
- - Added `Group.hasParent`
274
- - Added `Group.getChildren`
275
- - Added `Group.getDescendants`
276
- - Added `Group.getDescendantTreeIds`
277
- - Added `Group.hasChildren`
278
- - Added `Group.isLeaf`
279
- - Added `Group.isRoot`
280
- - Added `Group.getDepth`
281
- - Added `Group.getRoot`
282
- - Added `Group.getRootName`
283
- - Added `Group.hasAccounts`
284
-
285
- **November 2024**
286
-
287
- - Added `Transaction.trash`
288
- - Added `Transaction.untrash`
289
- - Added `Transaction.getAmountFormatted`
290
- - Added `Transaction.isLocked`
291
- - Removed `Transaction.remove` from `Transaction`
292
- - Removed `Transaction.restore` from `Transaction`
293
-
294
- **October 2024**
295
-
296
- - Exposed `payload` property on all objects from `bkper-js` interface
297
- - Added `Collection.addBooks`
298
- - Added `Collection.create`
299
- - Added `Collection.getOwnerUsername`
300
- - Added `Collection.getPermission`
301
- - Added `Collection.getUpdatedAt`
302
- - Added `Collection.remove`
303
- - Added `Collection.removeBooks`
304
- - Added `Collection.setName`
305
- - Added `Collection.update`
306
- - Added `Bkper.getBillingPortalUrl`
307
- - Added `Connection.getDateAddedMs`
308
- - Added `Connection.getLogo`
309
- - Added `Connection.remove`
310
- - Added `Integration.getAddedBy`
311
- - Added `Integration.getAgentId`
312
- - Added `Integration.getDateAddedMs`
313
- - Added `Integration.getLastUpdateMs`
314
- - Added `Integration.getLogo`
315
- - Added `Integration.remove`
316
- - Added `TransactionList` returned from `Book.listTransactions`
317
- - Removed `TransactionIterator` from `Transaction`
318
- - Removed `newTransaction` from `Book`. Use `Transaction` constructor instead
319
- - Removed `newAccount` from `Book`. Use `Account` constructor instead
320
- - Removed `newGroup` from `Book`. Use `Group` constructor instead
321
- - Removed `newFile` from `Book`. Use `File` constructor instead
322
-
323
- **September 2024**
324
-
325
- - Extracted `bkper-js` from `bkper` as a standalone library.
326
- - Added `Config.requestRetryHandler`
327
- - Added `Visibility` enum
328
- - Added `App.json`
329
- - Added `Bkper.getApps`
330
- - Added `Bkper.getBooks`
331
- - Added `Bkper.getTemplates`
332
- - Added `Bkper.newBook`
333
- - Added `Book.getTotalTransactions`
334
- - Added `Book.getTotalTransactionsCurrentMonth`
335
- - Added `Book.getTotalTransactionsCurrentYear`
336
- - Added `Book.getVisibility`
337
- - Added `Book.create`
338
- - Added `Collection.json`
339
- - Added `Template`
340
- - Added `Template.getBookId`
341
- - Added `Template.getBookLink`
342
- - Added `Template.getCategory`
343
- - Added `Template.getDescription`
344
- - Added `Template.getImageUrl`
345
- - Added `Template.getName`
346
- - Added `Template.getSheetsLink`
347
- - Added `Template.getTimesUsed`
348
- - Added `Template.json`
349
- - Added `User.getEmail`
350
- - Added `User.getHostedDomain`
351
- - Added `User.isFree`
352
- - Added `User.hasStartedTrial`
353
- - Added `User.getDaysLeftInTrial`
354
- - Added `User.hasUsedConnections`
355
- - Added `User.json`
356
-
357
- **January 2024**
358
-
359
- - Added `Transaction.setChecked`
360
-
361
- ## 2023
362
-
363
- **June 2023**
364
-
365
- - Added `Bkper.getUser`
366
- - Added `Bkper.setConfig`
367
- - Added `Book.batchTrashTransactions`
368
- - Added `Book.createIntegration`
369
- - Added `Book.getIntegrations`
370
- - Added `Book.updateIntegration`
371
- - Added `Config` interface
372
- - Added `Connection`
373
- - Added `Connection.clearTokenProperties`
374
- - Added `Connection.create`
375
- - Added `Connection.deleteProperty`
376
- - Added `Connection.getAgentId`
377
- - Added `Connection.getEmail`
378
- - Added `Connection.getId`
379
- - Added `Connection.getIntegrations`
380
- - Added `Connection.getName`
381
- - Added `Connection.getProperties`
382
- - Added `Connection.getProperty`
383
- - Added `Connection.getPropertyKeys`
384
- - Added `Connection.getType`
385
- - Added `Connection.getUUID`
386
- - Added `Connection.json`
387
- - Added `Connection.setAgentId`
388
- - Added `Connection.setName`
389
- - Added `Connection.setProperties`
390
- - Added `Connection.setProperty`
391
- - Added `Connection.setType`
392
- - Added `Connection.setUUID`
393
- - Added `Integration`
394
- - Added `Integration.deleteProperty`
395
- - Added `Integration.getBookId`
396
- - Added `Integration.getId`
397
- - Added `Integration.getName`
398
- - Added `Integration.getProperties`
399
- - Added `Integration.getProperty`
400
- - Added `Integration.json`
401
- - Added `Integration.setProperties`
402
- - Added `Integration.setProperty`
403
- - Added `User`
404
- - Added `User.getConnection`
405
- - Added `User.getConnections`
406
- - Added `User.getFullName`
407
- - Added `User.getId`
408
- - Added `User.getName`
409
- - Deprecated `Bkper.setApiKey`
410
- - Deprecated `Bkper.setOAuthTokenProvider`
411
-
412
- ## 2022
413
-
414
- **September 2022**
415
-
416
- - Deprecated `Account.getBalance`
417
-
418
- **May 2022**
419
-
420
- - Added `Book.parseDate`
421
-
422
- **April 2022**
423
-
424
- - Added `Book.getClosingDate`
425
- - Added `Book.setClosingDate`
426
-
427
- ## 2021
428
-
429
- **October 2021**
430
-
431
- - Added `Book.getGroupsByAccount`
432
-
433
- **May 2021**
434
-
435
- - Added `Group.getParent`
436
- - Added `Group.setParent`
437
- - **BREAKING CHANGE:** Removed `AccountsDataTableBuilder`
438
- - **BREAKING CHANGE:** Removed `BalancesDataTableBuilder`
439
- - **BREAKING CHANGE:** Removed `TransactionsDataTableBuilder`
440
- - **BREAKING CHANGE:** Removed `BalancesReport`
441
- - **BREAKING CHANGE:** Removed `Balance`
442
- - **BREAKING CHANGE:** Removed `BalancesContainer`
443
-
444
- **April 2021**
445
-
446
- - Added `Book.getLockDate`
447
- - Added `Book.setLockDate`
448
-
449
- **March 2021**
450
-
451
- - **BREAKING CHANGE:** Removed `BalanceCheckedType`
452
-
453
- **February 2021**
454
-
455
- - Added `Book.getPeriod`
456
- - Added `Book.setPeriod`
457
- - Added `Book.getPeriodStartMonth`
458
- - Added `Book.setPeriodStartMonth`
459
- - Added `Book.getPageSize`
460
- - Added `Book.setPageSize`
461
-
462
- **January 2021**
463
-
464
- - `bkper` client library published