@whocomply/ledger 0.1.0
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/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/index.cjs +559 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +590 -0
- package/dist/index.d.ts +590 -0
- package/dist/index.js +530 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
interface LedgerClientOptions {
|
|
2
|
+
/** Ledger API origin, e.g. https://ledger.internal.example.com or http://localhost:8080 */
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
/** Tenant slug all requests are scoped to */
|
|
5
|
+
tenant: string;
|
|
6
|
+
/** Machine access: sent as X-API-Key. Create keys in the dashboard under Settings. */
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
/** User access: sent as Authorization: Bearer. Mostly for dashboards. */
|
|
9
|
+
token?: string;
|
|
10
|
+
/** Override fetch (testing, custom agents). Defaults to globalThis.fetch. */
|
|
11
|
+
fetch?: typeof fetch;
|
|
12
|
+
/** Per-request timeout in milliseconds. No timeout when omitted. */
|
|
13
|
+
timeoutMs?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Strict idempotency: posting/reversal/draft methods throw when called
|
|
16
|
+
* without an explicit idempotencyKey instead of auto-generating one.
|
|
17
|
+
*/
|
|
18
|
+
requireIdempotencyKey?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Per-call options accepted by every SDK method. */
|
|
21
|
+
interface RequestOptions {
|
|
22
|
+
/** Abort the request (combined with the client timeout when both are set). */
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
}
|
|
25
|
+
type Query = Record<string, string | number | undefined>;
|
|
26
|
+
interface InternalRequestOptions {
|
|
27
|
+
query?: Query;
|
|
28
|
+
body?: unknown;
|
|
29
|
+
/** Return the raw response text instead of unwrapping the JSON envelope (CSV exports). */
|
|
30
|
+
raw?: boolean;
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
}
|
|
33
|
+
declare class HttpClient {
|
|
34
|
+
private readonly baseUrl;
|
|
35
|
+
private readonly headers;
|
|
36
|
+
private readonly fetchImpl;
|
|
37
|
+
private readonly timeoutMs?;
|
|
38
|
+
readonly tenant: string;
|
|
39
|
+
readonly requireIdempotencyKey: boolean;
|
|
40
|
+
constructor(options: LedgerClientOptions);
|
|
41
|
+
/** Path inside the tenant scope, e.g. tenantPath('/accounts') */
|
|
42
|
+
tenantPath(path: string): string;
|
|
43
|
+
private effectiveSignal;
|
|
44
|
+
request<T>(method: string, path: string, options?: InternalRequestOptions): Promise<T>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type AccountType = 'asset' | 'liability' | 'equity' | 'revenue' | 'expense';
|
|
48
|
+
type EntrySide = 'debit' | 'credit';
|
|
49
|
+
type TransactionStatus = 'draft' | 'pending' | 'posted' | 'failed' | 'rejected';
|
|
50
|
+
type PeriodStatus = 'open' | 'closed';
|
|
51
|
+
interface Account {
|
|
52
|
+
id: string;
|
|
53
|
+
code: string;
|
|
54
|
+
name: string;
|
|
55
|
+
account_type: AccountType;
|
|
56
|
+
parent_code?: string;
|
|
57
|
+
currency: string;
|
|
58
|
+
allow_negative: boolean;
|
|
59
|
+
is_active: boolean;
|
|
60
|
+
metadata?: Record<string, unknown>;
|
|
61
|
+
created_at: string;
|
|
62
|
+
updated_at: string;
|
|
63
|
+
}
|
|
64
|
+
interface CreateAccountInput {
|
|
65
|
+
code: string;
|
|
66
|
+
name: string;
|
|
67
|
+
account_type: AccountType;
|
|
68
|
+
parent_code?: string;
|
|
69
|
+
currency?: string;
|
|
70
|
+
allow_negative?: boolean;
|
|
71
|
+
metadata?: Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
interface UpdateAccountInput {
|
|
74
|
+
name?: string;
|
|
75
|
+
allow_negative?: boolean;
|
|
76
|
+
metadata?: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
interface AccountsPage {
|
|
79
|
+
accounts: Account[];
|
|
80
|
+
page: number;
|
|
81
|
+
page_size: number;
|
|
82
|
+
total: number;
|
|
83
|
+
total_pages: number;
|
|
84
|
+
}
|
|
85
|
+
interface ListAccountsParams {
|
|
86
|
+
accountType?: AccountType;
|
|
87
|
+
parentCode?: string;
|
|
88
|
+
currency?: string;
|
|
89
|
+
search?: string;
|
|
90
|
+
page?: number;
|
|
91
|
+
pageSize?: number;
|
|
92
|
+
}
|
|
93
|
+
interface AccountBalance {
|
|
94
|
+
currency: string;
|
|
95
|
+
balance: string;
|
|
96
|
+
version: number;
|
|
97
|
+
}
|
|
98
|
+
interface AsOfBalance {
|
|
99
|
+
account_id: string;
|
|
100
|
+
currency: string;
|
|
101
|
+
balance: string;
|
|
102
|
+
as_of: string;
|
|
103
|
+
}
|
|
104
|
+
interface AccountStats {
|
|
105
|
+
total_accounts: number;
|
|
106
|
+
asset_accounts: number;
|
|
107
|
+
liability_accounts: number;
|
|
108
|
+
equity_accounts: number;
|
|
109
|
+
revenue_accounts: number;
|
|
110
|
+
expense_accounts: number;
|
|
111
|
+
currencies_count: number;
|
|
112
|
+
}
|
|
113
|
+
interface EntryLineInput {
|
|
114
|
+
account_code: string;
|
|
115
|
+
amount: string;
|
|
116
|
+
side: EntrySide;
|
|
117
|
+
currency: string;
|
|
118
|
+
/** Up to 4 flat string tags, e.g. { product: "wallet", region: "lagos" } */
|
|
119
|
+
dimensions?: Record<string, string>;
|
|
120
|
+
metadata?: Record<string, unknown>;
|
|
121
|
+
}
|
|
122
|
+
interface PostEntryInput {
|
|
123
|
+
description: string;
|
|
124
|
+
entries: EntryLineInput[];
|
|
125
|
+
/**
|
|
126
|
+
* Generated automatically when omitted, unless the client was built with
|
|
127
|
+
* requireIdempotencyKey: true (then omission throws).
|
|
128
|
+
*/
|
|
129
|
+
idempotencyKey?: string;
|
|
130
|
+
reference?: string;
|
|
131
|
+
/** RFC3339 backdating timestamp; requires the transactions:backdate scope. */
|
|
132
|
+
postedAt?: string;
|
|
133
|
+
metadata?: Record<string, unknown>;
|
|
134
|
+
}
|
|
135
|
+
interface Transaction {
|
|
136
|
+
id: string;
|
|
137
|
+
idempotency_key: string;
|
|
138
|
+
description: string;
|
|
139
|
+
reference?: string;
|
|
140
|
+
reverses_transaction_id?: string;
|
|
141
|
+
created_by?: string;
|
|
142
|
+
approved_by?: string;
|
|
143
|
+
status: TransactionStatus;
|
|
144
|
+
posted_at: string;
|
|
145
|
+
created_at: string;
|
|
146
|
+
metadata?: Record<string, unknown>;
|
|
147
|
+
}
|
|
148
|
+
interface TransactionLine {
|
|
149
|
+
id: string;
|
|
150
|
+
account_id: string;
|
|
151
|
+
account_code: string;
|
|
152
|
+
account_name: string;
|
|
153
|
+
amount: string;
|
|
154
|
+
side: EntrySide;
|
|
155
|
+
currency: string;
|
|
156
|
+
dimensions?: Record<string, string>;
|
|
157
|
+
created_at: string;
|
|
158
|
+
}
|
|
159
|
+
interface Pagination {
|
|
160
|
+
total: number;
|
|
161
|
+
limit: number;
|
|
162
|
+
offset: number;
|
|
163
|
+
has_more: boolean;
|
|
164
|
+
}
|
|
165
|
+
interface TransactionsPage {
|
|
166
|
+
transactions: Transaction[] | null;
|
|
167
|
+
pagination: Pagination;
|
|
168
|
+
}
|
|
169
|
+
interface ListTransactionsParams {
|
|
170
|
+
limit?: number;
|
|
171
|
+
offset?: number;
|
|
172
|
+
accountCode?: string;
|
|
173
|
+
/** Exact match on the consumer-supplied reference (ops lookup path). */
|
|
174
|
+
reference?: string;
|
|
175
|
+
/** Attach lines to every row in the same call (no N+1). */
|
|
176
|
+
includeLines?: boolean;
|
|
177
|
+
/** Filter by lifecycle state; 'draft' is the approvals queue */
|
|
178
|
+
status?: TransactionStatus;
|
|
179
|
+
/** YYYY-MM-DD; requires endDate */
|
|
180
|
+
startDate?: string;
|
|
181
|
+
/** YYYY-MM-DD; requires startDate */
|
|
182
|
+
endDate?: string;
|
|
183
|
+
}
|
|
184
|
+
interface Currency {
|
|
185
|
+
code: string;
|
|
186
|
+
name: string;
|
|
187
|
+
exponent: number;
|
|
188
|
+
is_active: boolean;
|
|
189
|
+
created_at: string;
|
|
190
|
+
updated_at: string;
|
|
191
|
+
}
|
|
192
|
+
interface RegisterCurrencyInput {
|
|
193
|
+
code: string;
|
|
194
|
+
/** Decimal places enforced on postings: NGN 2, USDT 6, BTC 8, ETH 18 */
|
|
195
|
+
exponent: number;
|
|
196
|
+
name?: string;
|
|
197
|
+
}
|
|
198
|
+
interface UpdateCurrencyInput {
|
|
199
|
+
name?: string;
|
|
200
|
+
exponent?: number;
|
|
201
|
+
is_active?: boolean;
|
|
202
|
+
}
|
|
203
|
+
interface AccountingPeriod {
|
|
204
|
+
id: string;
|
|
205
|
+
name: string;
|
|
206
|
+
starts_on: string;
|
|
207
|
+
ends_on: string;
|
|
208
|
+
status: PeriodStatus;
|
|
209
|
+
closed_at?: string;
|
|
210
|
+
created_at: string;
|
|
211
|
+
updated_at: string;
|
|
212
|
+
}
|
|
213
|
+
interface CreatePeriodInput {
|
|
214
|
+
name: string;
|
|
215
|
+
/** YYYY-MM-DD */
|
|
216
|
+
starts_on: string;
|
|
217
|
+
/** YYYY-MM-DD */
|
|
218
|
+
ends_on: string;
|
|
219
|
+
}
|
|
220
|
+
interface TrialBalanceRow {
|
|
221
|
+
account_id: string;
|
|
222
|
+
code: string;
|
|
223
|
+
name: string;
|
|
224
|
+
account_type: AccountType;
|
|
225
|
+
debit: string;
|
|
226
|
+
credit: string;
|
|
227
|
+
}
|
|
228
|
+
interface TrialBalanceCurrencyGroup {
|
|
229
|
+
currency: string;
|
|
230
|
+
rows: TrialBalanceRow[];
|
|
231
|
+
total_debit: string;
|
|
232
|
+
total_credit: string;
|
|
233
|
+
balanced: boolean;
|
|
234
|
+
}
|
|
235
|
+
interface TrialBalance {
|
|
236
|
+
as_of: string;
|
|
237
|
+
currencies: TrialBalanceCurrencyGroup[];
|
|
238
|
+
}
|
|
239
|
+
interface TransactionNote {
|
|
240
|
+
id: string;
|
|
241
|
+
author_id?: string;
|
|
242
|
+
note: string;
|
|
243
|
+
created_at: string;
|
|
244
|
+
}
|
|
245
|
+
interface StatementRow {
|
|
246
|
+
account_id: string;
|
|
247
|
+
code: string;
|
|
248
|
+
name: string;
|
|
249
|
+
amount: string;
|
|
250
|
+
}
|
|
251
|
+
interface ProfitAndLossCurrency {
|
|
252
|
+
currency: string;
|
|
253
|
+
revenue: StatementRow[] | null;
|
|
254
|
+
expenses: StatementRow[] | null;
|
|
255
|
+
total_revenue: string;
|
|
256
|
+
total_expenses: string;
|
|
257
|
+
net_income: string;
|
|
258
|
+
}
|
|
259
|
+
interface ProfitAndLoss {
|
|
260
|
+
start_date: string;
|
|
261
|
+
end_date: string;
|
|
262
|
+
currencies: ProfitAndLossCurrency[] | null;
|
|
263
|
+
}
|
|
264
|
+
interface BalanceSheetCurrency {
|
|
265
|
+
currency: string;
|
|
266
|
+
assets: StatementRow[] | null;
|
|
267
|
+
liabilities: StatementRow[] | null;
|
|
268
|
+
equity: StatementRow[] | null;
|
|
269
|
+
total_assets: string;
|
|
270
|
+
total_liabilities: string;
|
|
271
|
+
total_equity: string;
|
|
272
|
+
balanced: boolean;
|
|
273
|
+
}
|
|
274
|
+
interface BalanceSheet {
|
|
275
|
+
as_of: string;
|
|
276
|
+
currencies: BalanceSheetCurrency[] | null;
|
|
277
|
+
}
|
|
278
|
+
interface GeneralLedgerEntry {
|
|
279
|
+
transaction_id: string;
|
|
280
|
+
description: string;
|
|
281
|
+
reference?: string;
|
|
282
|
+
posted_at: string;
|
|
283
|
+
debit: string;
|
|
284
|
+
credit: string;
|
|
285
|
+
running_balance: string;
|
|
286
|
+
}
|
|
287
|
+
interface GeneralLedger {
|
|
288
|
+
account_id: string;
|
|
289
|
+
code: string;
|
|
290
|
+
name: string;
|
|
291
|
+
account_type: AccountType;
|
|
292
|
+
currency: string;
|
|
293
|
+
start_date: string;
|
|
294
|
+
end_date: string;
|
|
295
|
+
opening_balance: string;
|
|
296
|
+
entries: GeneralLedgerEntry[] | null;
|
|
297
|
+
closing_balance: string;
|
|
298
|
+
}
|
|
299
|
+
interface FxPosition {
|
|
300
|
+
currency: string;
|
|
301
|
+
assets: string;
|
|
302
|
+
liabilities: string;
|
|
303
|
+
net_position: string;
|
|
304
|
+
rate: string;
|
|
305
|
+
base_equivalent: string;
|
|
306
|
+
}
|
|
307
|
+
interface FxExposure {
|
|
308
|
+
as_of: string;
|
|
309
|
+
base_currency: string;
|
|
310
|
+
positions: FxPosition[] | null;
|
|
311
|
+
}
|
|
312
|
+
type RecurringFrequency = 'daily' | 'weekly' | 'monthly';
|
|
313
|
+
interface RecurringJournal {
|
|
314
|
+
id: string;
|
|
315
|
+
name: string;
|
|
316
|
+
description: string;
|
|
317
|
+
reference?: string;
|
|
318
|
+
frequency: RecurringFrequency;
|
|
319
|
+
next_run_on: string;
|
|
320
|
+
last_run_on?: string;
|
|
321
|
+
is_active: boolean;
|
|
322
|
+
entries: EntryLineInput[];
|
|
323
|
+
created_at: string;
|
|
324
|
+
}
|
|
325
|
+
interface CreateRecurringJournalInput {
|
|
326
|
+
name: string;
|
|
327
|
+
description: string;
|
|
328
|
+
reference?: string;
|
|
329
|
+
frequency: RecurringFrequency;
|
|
330
|
+
/** YYYY-MM-DD of the first posting */
|
|
331
|
+
starts_on: string;
|
|
332
|
+
entries: EntryLineInput[];
|
|
333
|
+
}
|
|
334
|
+
interface ListBalancesParams {
|
|
335
|
+
limit?: number;
|
|
336
|
+
offset?: number;
|
|
337
|
+
codePrefix?: string;
|
|
338
|
+
codeSuffix?: string;
|
|
339
|
+
currency?: string;
|
|
340
|
+
/** Account metadata containment filter, e.g. { org_id: '...' } */
|
|
341
|
+
metadata?: Record<string, string>;
|
|
342
|
+
}
|
|
343
|
+
interface BulkBalanceRow {
|
|
344
|
+
account_code: string;
|
|
345
|
+
currency: string;
|
|
346
|
+
balance: string;
|
|
347
|
+
version: number;
|
|
348
|
+
}
|
|
349
|
+
interface BalancesPage {
|
|
350
|
+
balances: BulkBalanceRow[];
|
|
351
|
+
total: number;
|
|
352
|
+
limit: number;
|
|
353
|
+
offset: number;
|
|
354
|
+
has_more: boolean;
|
|
355
|
+
}
|
|
356
|
+
interface LedgerEvent {
|
|
357
|
+
id: string;
|
|
358
|
+
sequence: number;
|
|
359
|
+
type: string;
|
|
360
|
+
aggregate_type: string;
|
|
361
|
+
aggregate_id: string;
|
|
362
|
+
data: unknown;
|
|
363
|
+
created_at: string;
|
|
364
|
+
}
|
|
365
|
+
interface EventsPage {
|
|
366
|
+
events: LedgerEvent[];
|
|
367
|
+
next_cursor: number;
|
|
368
|
+
has_more: boolean;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
declare class AccountsResource {
|
|
372
|
+
private readonly http;
|
|
373
|
+
constructor(http: HttpClient);
|
|
374
|
+
create(input: CreateAccountInput, options?: RequestOptions): Promise<Account>;
|
|
375
|
+
list(params?: ListAccountsParams, options?: RequestOptions): Promise<AccountsPage>;
|
|
376
|
+
get(accountId: string, options?: RequestOptions): Promise<Account>;
|
|
377
|
+
getByCode(code: string, options?: RequestOptions): Promise<Account>;
|
|
378
|
+
update(accountId: string, input: UpdateAccountInput, options?: RequestOptions): Promise<Account>;
|
|
379
|
+
deactivate(accountId: string, options?: RequestOptions): Promise<{
|
|
380
|
+
message: string;
|
|
381
|
+
}>;
|
|
382
|
+
/** Current materialized balance. Currency defaults to the tenant base currency. */
|
|
383
|
+
balance(accountId: string, options?: RequestOptions & {
|
|
384
|
+
currency?: string;
|
|
385
|
+
}): Promise<AccountBalance>;
|
|
386
|
+
/** Journal-derived balance through the end of a past day (YYYY-MM-DD, UTC). */
|
|
387
|
+
balanceAsOf(accountId: string, asOf: string, options?: RequestOptions & {
|
|
388
|
+
currency?: string;
|
|
389
|
+
}): Promise<AsOfBalance>;
|
|
390
|
+
hierarchy(options?: RequestOptions): Promise<Account[]>;
|
|
391
|
+
stats(options?: RequestOptions): Promise<AccountStats>;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
declare class BalancesResource {
|
|
395
|
+
private readonly http;
|
|
396
|
+
constructor(http: HttpClient);
|
|
397
|
+
/**
|
|
398
|
+
* Bulk balances: every (account, currency) row with its monotonic
|
|
399
|
+
* version. Filter by codePrefix/codeSuffix, currency, or account
|
|
400
|
+
* metadata containment (e.g. { org_id: '...' }).
|
|
401
|
+
*/
|
|
402
|
+
list(params?: ListBalancesParams, options?: RequestOptions): Promise<BalancesPage>;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
declare class EventsResource {
|
|
406
|
+
private readonly http;
|
|
407
|
+
constructor(http: HttpClient);
|
|
408
|
+
/**
|
|
409
|
+
* Durable event feed, strictly ordered by sequence. Poll with
|
|
410
|
+
* afterId = the last sequence you processed; store next_cursor.
|
|
411
|
+
*/
|
|
412
|
+
list(params?: {
|
|
413
|
+
afterId?: number;
|
|
414
|
+
limit?: number;
|
|
415
|
+
}, options?: RequestOptions): Promise<EventsPage>;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
declare class CurrenciesResource {
|
|
419
|
+
private readonly http;
|
|
420
|
+
constructor(http: HttpClient);
|
|
421
|
+
/**
|
|
422
|
+
* Register a currency with its precision policy. Postings beyond the
|
|
423
|
+
* exponent's decimal places are rejected. Unregistered currencies fall
|
|
424
|
+
* back to the storage maximum of 18 decimal places.
|
|
425
|
+
*/
|
|
426
|
+
register(input: RegisterCurrencyInput, options?: RequestOptions): Promise<Currency>;
|
|
427
|
+
list(options?: RequestOptions): Promise<Currency[]>;
|
|
428
|
+
update(code: string, input: UpdateCurrencyInput, options?: RequestOptions): Promise<Currency>;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
declare class PeriodsResource {
|
|
432
|
+
private readonly http;
|
|
433
|
+
constructor(http: HttpClient);
|
|
434
|
+
/** Periods of one tenant may not overlap; violations raise a 409. */
|
|
435
|
+
create(input: CreatePeriodInput, options?: RequestOptions): Promise<AccountingPeriod>;
|
|
436
|
+
list(options?: RequestOptions): Promise<AccountingPeriod[]>;
|
|
437
|
+
/**
|
|
438
|
+
* Close a period. Enforced by the database: nothing can post into a
|
|
439
|
+
* closed period, and posting attempts raise a 409.
|
|
440
|
+
*/
|
|
441
|
+
close(periodId: string, options?: RequestOptions): Promise<AccountingPeriod>;
|
|
442
|
+
reopen(periodId: string, options?: RequestOptions): Promise<AccountingPeriod>;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
declare class RecurringJournalsResource {
|
|
446
|
+
private readonly http;
|
|
447
|
+
constructor(http: HttpClient);
|
|
448
|
+
/**
|
|
449
|
+
* Register a repeating journal. Each occurrence posts exactly once: the
|
|
450
|
+
* worker derives the idempotency key from (schedule id, run date).
|
|
451
|
+
*/
|
|
452
|
+
create(input: CreateRecurringJournalInput, options?: RequestOptions): Promise<RecurringJournal>;
|
|
453
|
+
list(options?: RequestOptions): Promise<RecurringJournal[]>;
|
|
454
|
+
pause(scheduleId: string, options?: RequestOptions): Promise<RecurringJournal>;
|
|
455
|
+
resume(scheduleId: string, options?: RequestOptions): Promise<RecurringJournal>;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
declare class ReportsResource {
|
|
459
|
+
private readonly http;
|
|
460
|
+
constructor(http: HttpClient);
|
|
461
|
+
/**
|
|
462
|
+
* Trial balance derived from posted journal lines, grouped by currency.
|
|
463
|
+
* asOf (YYYY-MM-DD) means "through the end of that day, UTC"; defaults
|
|
464
|
+
* to now.
|
|
465
|
+
*/
|
|
466
|
+
trialBalance(options?: RequestOptions & {
|
|
467
|
+
asOf?: string;
|
|
468
|
+
}): Promise<TrialBalance>;
|
|
469
|
+
/** Revenue and expenses over an inclusive date range, optionally filtered by dimensions. */
|
|
470
|
+
profitAndLoss(options: RequestOptions & {
|
|
471
|
+
startDate: string;
|
|
472
|
+
endDate: string;
|
|
473
|
+
dimensions?: Record<string, string>;
|
|
474
|
+
}): Promise<ProfitAndLoss>;
|
|
475
|
+
/** Assets, liabilities, and equity (with computed retained earnings) as of a date. */
|
|
476
|
+
balanceSheet(options?: RequestOptions & {
|
|
477
|
+
asOf?: string;
|
|
478
|
+
}): Promise<BalanceSheet>;
|
|
479
|
+
/** One account's activity with opening, running, and closing balances. */
|
|
480
|
+
generalLedger(options: RequestOptions & {
|
|
481
|
+
accountCode: string;
|
|
482
|
+
startDate: string;
|
|
483
|
+
endDate: string;
|
|
484
|
+
currency?: string;
|
|
485
|
+
}): Promise<GeneralLedger>;
|
|
486
|
+
/** Per-currency net positions with base equivalents at the provided rates. */
|
|
487
|
+
fxExposure(options?: RequestOptions & {
|
|
488
|
+
rates?: Record<string, string>;
|
|
489
|
+
asOf?: string;
|
|
490
|
+
}): Promise<FxExposure>;
|
|
491
|
+
/**
|
|
492
|
+
* Posted journals as a Xero manual-journal import CSV (raw string).
|
|
493
|
+
* Dates are inclusive. Currency defaults to the tenant base currency.
|
|
494
|
+
*/
|
|
495
|
+
xeroJournalsCsv(options: RequestOptions & {
|
|
496
|
+
startDate: string;
|
|
497
|
+
endDate: string;
|
|
498
|
+
currency?: string;
|
|
499
|
+
}): Promise<string>;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
declare class TransactionsResource {
|
|
503
|
+
private readonly http;
|
|
504
|
+
constructor(http: HttpClient);
|
|
505
|
+
private idempotencyKey;
|
|
506
|
+
/**
|
|
507
|
+
* Post a balanced double-entry transaction. Debits must equal credits per
|
|
508
|
+
* currency or the API rejects with UNBALANCED_TRANSACTION. posted_at
|
|
509
|
+
* backdates the posting and requires the transactions:backdate scope.
|
|
510
|
+
*/
|
|
511
|
+
post(input: PostEntryInput, options?: RequestOptions): Promise<Transaction>;
|
|
512
|
+
get(transactionId: string, options?: RequestOptions & {
|
|
513
|
+
includeLines?: boolean;
|
|
514
|
+
}): Promise<Transaction>;
|
|
515
|
+
lines(transactionId: string, options?: RequestOptions): Promise<TransactionLine[]>;
|
|
516
|
+
list(params?: ListTransactionsParams, options?: RequestOptions): Promise<TransactionsPage>;
|
|
517
|
+
/**
|
|
518
|
+
* Maker-checker: store a fully validated entry with zero balance impact.
|
|
519
|
+
* Balances apply only when a DIFFERENT actor approves.
|
|
520
|
+
*/
|
|
521
|
+
draft(input: PostEntryInput, options?: RequestOptions): Promise<Transaction>;
|
|
522
|
+
/** Approve a draft (requires the transactions:approve scope and a different actor). */
|
|
523
|
+
approve(transactionId: string, options?: RequestOptions): Promise<Transaction>;
|
|
524
|
+
/** Reject a draft; it never had balance impact. */
|
|
525
|
+
reject(transactionId: string, options?: RequestOptions): Promise<Transaction>;
|
|
526
|
+
/** Append an immutable note (audit support). */
|
|
527
|
+
addNote(transactionId: string, note: string, options?: RequestOptions): Promise<TransactionNote>;
|
|
528
|
+
listNotes(transactionId: string, options?: RequestOptions): Promise<TransactionNote[]>;
|
|
529
|
+
/**
|
|
530
|
+
* Post a reversal: a new transaction mirroring the original with debits
|
|
531
|
+
* and credits swapped, linked via reverses_transaction_id. A transaction
|
|
532
|
+
* can be reversed at most once; a second attempt raises ALREADY_REVERSED.
|
|
533
|
+
*/
|
|
534
|
+
reverse(transactionId: string, reverseOptions?: {
|
|
535
|
+
idempotencyKey?: string;
|
|
536
|
+
description?: string;
|
|
537
|
+
metadata?: Record<string, unknown>;
|
|
538
|
+
}, options?: RequestOptions): Promise<Transaction>;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/** Stable machine-readable error codes; branch on these, never on message text. */
|
|
542
|
+
type LedgerErrorCode = 'INSUFFICIENT_BALANCE' | 'UNBALANCED_TRANSACTION' | 'AMOUNT_PRECISION' | 'AMOUNT_TOO_LARGE' | 'CURRENCY_DEACTIVATED' | 'CURRENCY_PRECISION' | 'PERIOD_CLOSED' | 'ALREADY_REVERSED' | 'CANNOT_REVERSE_UNPOSTED' | 'ACCOUNT_NOT_FOUND' | 'ACCOUNT_EXISTS' | 'IDEMPOTENCY_CONFLICT' | 'VALIDATION_ERROR' | 'NOT_DRAFT' | 'SELF_APPROVAL' | 'TRANSACTION_NOT_FOUND' | (string & {});
|
|
543
|
+
/** Structured detail attached to INSUFFICIENT_BALANCE errors. */
|
|
544
|
+
interface InsufficientBalanceDetails {
|
|
545
|
+
account_code: string;
|
|
546
|
+
currency: string;
|
|
547
|
+
/** Decimal strings; render customer copy from these, never parse prose. */
|
|
548
|
+
attempted: string;
|
|
549
|
+
available: string;
|
|
550
|
+
}
|
|
551
|
+
/** Error raised for any non-success response from the ledger API. */
|
|
552
|
+
declare class LedgerApiError extends Error {
|
|
553
|
+
/** HTTP status code */
|
|
554
|
+
readonly status: number;
|
|
555
|
+
/** Alias for status, per the Alphaex integration contract. */
|
|
556
|
+
readonly httpStatus: number;
|
|
557
|
+
/** Stable machine-readable code (absent on transport-level failures). */
|
|
558
|
+
readonly code?: LedgerErrorCode;
|
|
559
|
+
/** Structured error context (e.g. InsufficientBalanceDetails). */
|
|
560
|
+
readonly details?: unknown;
|
|
561
|
+
/** Raw response body, when one could be read */
|
|
562
|
+
readonly body?: unknown;
|
|
563
|
+
constructor(status: number, message: string, options?: {
|
|
564
|
+
code?: string;
|
|
565
|
+
details?: unknown;
|
|
566
|
+
body?: unknown;
|
|
567
|
+
});
|
|
568
|
+
/** True for 409s: double reversals, closed periods, existing resources. */
|
|
569
|
+
get isConflict(): boolean;
|
|
570
|
+
/** Typed accessor for INSUFFICIENT_BALANCE detail. */
|
|
571
|
+
get insufficientBalance(): InsufficientBalanceDetails | undefined;
|
|
572
|
+
}
|
|
573
|
+
/** Thrown in strict idempotency mode when a mutating call omits the key. */
|
|
574
|
+
declare class MissingIdempotencyKeyError extends Error {
|
|
575
|
+
constructor(method: string);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
declare class LedgerClient {
|
|
579
|
+
readonly accounts: AccountsResource;
|
|
580
|
+
readonly balances: BalancesResource;
|
|
581
|
+
readonly events: EventsResource;
|
|
582
|
+
readonly transactions: TransactionsResource;
|
|
583
|
+
readonly currencies: CurrenciesResource;
|
|
584
|
+
readonly periods: PeriodsResource;
|
|
585
|
+
readonly recurringJournals: RecurringJournalsResource;
|
|
586
|
+
readonly reports: ReportsResource;
|
|
587
|
+
constructor(options: LedgerClientOptions);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
export { type Account, type AccountBalance, type AccountStats, type AccountType, type AccountingPeriod, type AccountsPage, type AsOfBalance, type BalanceSheet, type BalanceSheetCurrency, type BalancesPage, type BulkBalanceRow, type CreateAccountInput, type CreatePeriodInput, type CreateRecurringJournalInput, type Currency, type EntryLineInput, type EntrySide, type EventsPage, type FxExposure, type FxPosition, type GeneralLedger, type GeneralLedgerEntry, type InsufficientBalanceDetails, LedgerApiError, LedgerClient, type LedgerClientOptions, type LedgerErrorCode, type LedgerEvent, type ListAccountsParams, type ListBalancesParams, type ListTransactionsParams, MissingIdempotencyKeyError, type Pagination, type PeriodStatus, type PostEntryInput, type ProfitAndLoss, type ProfitAndLossCurrency, type RecurringFrequency, type RecurringJournal, type RegisterCurrencyInput, type RequestOptions, type StatementRow, type Transaction, type TransactionLine, type TransactionNote, type TransactionStatus, type TransactionsPage, type TrialBalance, type TrialBalanceCurrencyGroup, type TrialBalanceRow, type UpdateAccountInput, type UpdateCurrencyInput };
|