@moatless/ledgit-client 0.2.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.
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Ledgit API Client
3
+ *
4
+ * Company is derived from the JWT token, not passed in requests.
5
+ */
6
+ import { type BinaryDownloadResult } from "@moatless/api-client";
7
+ import type { JournalEntry, Document, FiscalYear, LedgerAccount } from "@moatless/bookkeeping-types";
8
+ import type { LedgitClientConfig, CompanyInfo, CompanyWithInbox, CreateCompanyRequest, CreateJournalEntryRequest, FileUploadOptions, InboxItem } from "./types";
9
+ export declare class LedgitClient {
10
+ private readonly httpClient;
11
+ constructor(config: LedgitClientConfig);
12
+ /**
13
+ * Make a raw GET request
14
+ */
15
+ private get;
16
+ /**
17
+ * Make a raw POST request
18
+ */
19
+ private post;
20
+ /**
21
+ * Make a raw DELETE request
22
+ */
23
+ private delete;
24
+ /**
25
+ * Get company information (derived from token)
26
+ */
27
+ getCompanyInfo(): Promise<CompanyInfo>;
28
+ /**
29
+ * Create/register a company and enable inbox email
30
+ * Returns company info with the generated inbox email address
31
+ */
32
+ createCompany(data: CreateCompanyRequest): Promise<CompanyWithInbox>;
33
+ /**
34
+ * Get all journal entries, optionally filtered by fiscal year
35
+ */
36
+ getJournalEntries(fiscalYear?: string): Promise<JournalEntry[]>;
37
+ /**
38
+ * Create a new journal entry
39
+ */
40
+ createJournalEntry(entry: CreateJournalEntryRequest): Promise<JournalEntry>;
41
+ /**
42
+ * Get all inbox items with their documents
43
+ * @param options.includeDeleted - Include items marked for deletion
44
+ */
45
+ getInbox(options?: {
46
+ includeDeleted?: boolean;
47
+ }): Promise<InboxItem[]>;
48
+ /**
49
+ * Download a file from an inbox item
50
+ * @param emailId The inbox item/email ID
51
+ * @param filename The filename to download
52
+ */
53
+ downloadInboxFile(emailId: string, filename: string): Promise<BinaryDownloadResult>;
54
+ /**
55
+ * Upload a document to the inbox
56
+ */
57
+ uploadDocument(options: FileUploadOptions): Promise<Document>;
58
+ /**
59
+ * Delete a document from the inbox
60
+ * @deprecated Use deleteInboxItem instead
61
+ */
62
+ deleteDocument(documentId: string): Promise<void>;
63
+ /**
64
+ * Mark an inbox item for deletion (soft delete)
65
+ * The item will be permanently deleted after the retention period.
66
+ */
67
+ deleteInboxItem(itemId: string): Promise<void>;
68
+ /**
69
+ * Get all fiscal years
70
+ */
71
+ getFiscalYears(): Promise<FiscalYear[]>;
72
+ /**
73
+ * Get the chart of accounts
74
+ */
75
+ getChartOfAccounts(): Promise<LedgerAccount[]>;
76
+ }
package/dist/client.js ADDED
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Ledgit API Client
3
+ *
4
+ * Company is derived from the JWT token, not passed in requests.
5
+ */
6
+ import { HttpClient, TokenBucketRateLimiter, validate, } from "@moatless/api-client";
7
+ import { LEDGIT_CONFIG } from "./config";
8
+ import { CompanyInfoResponseSchema, CreateCompanyResponseSchema, JournalEntriesResponseSchema, JournalEntryResponseSchema, DocumentResponseSchema, FiscalYearsResponseSchema, LedgerAccountsResponseSchema, InboxResponseSchema, } from "./schemas";
9
+ export class LedgitClient {
10
+ httpClient;
11
+ constructor(config) {
12
+ const rateLimiter = new TokenBucketRateLimiter(LEDGIT_CONFIG.RATE_LIMITER_CONFIG);
13
+ const baseUrl = config.baseUrl ?? LEDGIT_CONFIG.API_BASE_URL;
14
+ this.httpClient = new HttpClient({
15
+ baseUrl,
16
+ getAccessToken: config.getAccessToken,
17
+ rateLimiter,
18
+ timeout: LEDGIT_CONFIG.TIMEOUT_MS,
19
+ defaultHeaders: {
20
+ Accept: "application/json",
21
+ },
22
+ silent: config.silent,
23
+ });
24
+ }
25
+ /**
26
+ * Make a raw GET request
27
+ */
28
+ async get(path) {
29
+ return this.httpClient.get(path);
30
+ }
31
+ /**
32
+ * Make a raw POST request
33
+ */
34
+ async post(path, body) {
35
+ return this.httpClient.post(path, body);
36
+ }
37
+ /**
38
+ * Make a raw DELETE request
39
+ */
40
+ async delete(path) {
41
+ return this.httpClient.delete(path);
42
+ }
43
+ // ============================================================================
44
+ // Company Information
45
+ // ============================================================================
46
+ /**
47
+ * Get company information (derived from token)
48
+ */
49
+ async getCompanyInfo() {
50
+ const raw = await this.get("/api/company");
51
+ const response = validate(CompanyInfoResponseSchema, raw, "CompanyInfoResponse");
52
+ return response.data;
53
+ }
54
+ /**
55
+ * Create/register a company and enable inbox email
56
+ * Returns company info with the generated inbox email address
57
+ */
58
+ async createCompany(data) {
59
+ const raw = await this.post("/api/company", data);
60
+ const response = validate(CreateCompanyResponseSchema, raw, "CreateCompanyResponse");
61
+ return response.data;
62
+ }
63
+ // ============================================================================
64
+ // Journal Entries
65
+ // ============================================================================
66
+ /**
67
+ * Get all journal entries, optionally filtered by fiscal year
68
+ */
69
+ async getJournalEntries(fiscalYear) {
70
+ const query = fiscalYear ? `?fiscalYear=${fiscalYear}` : "";
71
+ const raw = await this.get(`/api/journal-entries${query}`);
72
+ const response = validate(JournalEntriesResponseSchema, raw, "JournalEntriesResponse");
73
+ return response.data;
74
+ }
75
+ /**
76
+ * Create a new journal entry
77
+ */
78
+ async createJournalEntry(entry) {
79
+ const raw = await this.post("/api/journal-entries", entry);
80
+ const response = validate(JournalEntryResponseSchema, raw, "JournalEntryResponse");
81
+ return response.data;
82
+ }
83
+ // ============================================================================
84
+ // Inbox / Documents
85
+ // ============================================================================
86
+ /**
87
+ * Get all inbox items with their documents
88
+ * @param options.includeDeleted - Include items marked for deletion
89
+ */
90
+ async getInbox(options) {
91
+ const query = options?.includeDeleted ? "?includeDeleted=true" : "";
92
+ const raw = await this.get(`/api/inbox${query}`);
93
+ const response = validate(InboxResponseSchema, raw, "InboxResponse");
94
+ return response.data;
95
+ }
96
+ /**
97
+ * Download a file from an inbox item
98
+ * @param emailId The inbox item/email ID
99
+ * @param filename The filename to download
100
+ */
101
+ async downloadInboxFile(emailId, filename) {
102
+ return this.httpClient.downloadBinary(`/api/inbox/${emailId}/${filename}`);
103
+ }
104
+ /**
105
+ * Upload a document to the inbox
106
+ */
107
+ async uploadDocument(options) {
108
+ const formData = new FormData();
109
+ const file = options.file instanceof Blob ? options.file : new Blob([options.file]);
110
+ formData.append("file", file, options.filename);
111
+ if (options.metadata) {
112
+ formData.append("metadata", JSON.stringify(options.metadata));
113
+ }
114
+ const raw = await this.httpClient.uploadFormData("/api/inbox", formData);
115
+ const response = validate(DocumentResponseSchema, raw, "DocumentResponse");
116
+ return response.data;
117
+ }
118
+ /**
119
+ * Delete a document from the inbox
120
+ * @deprecated Use deleteInboxItem instead
121
+ */
122
+ async deleteDocument(documentId) {
123
+ await this.delete(`/api/inbox/${documentId}`);
124
+ }
125
+ /**
126
+ * Mark an inbox item for deletion (soft delete)
127
+ * The item will be permanently deleted after the retention period.
128
+ */
129
+ async deleteInboxItem(itemId) {
130
+ await this.delete(`/api/inbox/${itemId}`);
131
+ }
132
+ // ============================================================================
133
+ // Fiscal Years
134
+ // ============================================================================
135
+ /**
136
+ * Get all fiscal years
137
+ */
138
+ async getFiscalYears() {
139
+ const raw = await this.get("/api/fiscal-years");
140
+ const response = validate(FiscalYearsResponseSchema, raw, "FiscalYearsResponse");
141
+ return response.data;
142
+ }
143
+ // ============================================================================
144
+ // Chart of Accounts
145
+ // ============================================================================
146
+ /**
147
+ * Get the chart of accounts
148
+ */
149
+ async getChartOfAccounts() {
150
+ const raw = await this.get("/api/accounts");
151
+ const response = validate(LedgerAccountsResponseSchema, raw, "LedgerAccountsResponse");
152
+ return response.data;
153
+ }
154
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Ledgit API configuration
3
+ */
4
+ export declare const LEDGIT_CONFIG: {
5
+ /**
6
+ * Base URL for the Ledgit API.
7
+ * Can be overridden via environment variable LEDGIT_API_URL
8
+ */
9
+ readonly API_BASE_URL: string;
10
+ /**
11
+ * API version prefix
12
+ */
13
+ readonly API_VERSION: "v1";
14
+ /**
15
+ * Rate limiter configuration
16
+ * Ledgit API has generous rate limits
17
+ */
18
+ readonly RATE_LIMITER_CONFIG: {
19
+ readonly maxTokens: 20;
20
+ readonly refillIntervalMs: 500;
21
+ readonly refillAmount: 2;
22
+ };
23
+ /**
24
+ * Request timeout in milliseconds (2 minutes)
25
+ */
26
+ readonly TIMEOUT_MS: 120000;
27
+ };
package/dist/config.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Ledgit API configuration
3
+ */
4
+ export const LEDGIT_CONFIG = {
5
+ /**
6
+ * Base URL for the Ledgit API.
7
+ * Can be overridden via environment variable LEDGIT_API_URL
8
+ */
9
+ API_BASE_URL: process.env.LEDGIT_API_URL ?? "https://api.ledgit.se",
10
+ /**
11
+ * API version prefix
12
+ */
13
+ API_VERSION: "v1",
14
+ /**
15
+ * Rate limiter configuration
16
+ * Ledgit API has generous rate limits
17
+ */
18
+ RATE_LIMITER_CONFIG: {
19
+ maxTokens: 20,
20
+ refillIntervalMs: 500,
21
+ refillAmount: 2,
22
+ },
23
+ /**
24
+ * Request timeout in milliseconds (2 minutes)
25
+ */
26
+ TIMEOUT_MS: 120000,
27
+ };
@@ -0,0 +1,5 @@
1
+ export { LedgitClient } from "./client";
2
+ export { LEDGIT_CONFIG } from "./config";
3
+ export type { LedgitClientConfig, CompanyInfo, CompanyWithInbox, CreateCompanyRequest, CreateJournalEntryRequest, DocumentUploadMetadata, FileUploadOptions, ApiResponse, PaginatedApiResponse, InboxItem, } from "./types";
4
+ export type { JournalEntry, JournalLine, JournalEntrySeries, JournalEntryStatus, MoneyAmount, Document, DocumentKind, DocumentStatus, DocumentMoneyAmount, TaxDetail, FiscalYear, LedgerAccount, } from "@moatless/bookkeeping-types";
5
+ export { JournalEntrySchema, DocumentSchema, FiscalYearSchema, LedgerAccountSchema, CompanyInfoSchema, CompanyWithInboxSchema, InboxItemSchema, InboxResponseSchema, } from "./schemas";
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ // Client
2
+ export { LedgitClient } from "./client";
3
+ // Configuration
4
+ export { LEDGIT_CONFIG } from "./config";
5
+ // Schemas (for consumers who want to do their own validation)
6
+ export { JournalEntrySchema, DocumentSchema, FiscalYearSchema, LedgerAccountSchema, CompanyInfoSchema, CompanyWithInboxSchema, InboxItemSchema, InboxResponseSchema, } from "./schemas";
@@ -0,0 +1,605 @@
1
+ /**
2
+ * Zod schemas for Ledgit API validation
3
+ */
4
+ import { z } from "zod";
5
+ export declare const JournalEntrySchema: z.ZodObject<{
6
+ id: z.ZodOptional<z.ZodString>;
7
+ series: z.ZodOptional<z.ZodEnum<{
8
+ A: "A";
9
+ B: "B";
10
+ C: "C";
11
+ D: "D";
12
+ E: "E";
13
+ I: "I";
14
+ M: "M";
15
+ }>>;
16
+ entryNumber: z.ZodNumber;
17
+ entryDate: z.ZodString;
18
+ description: z.ZodString;
19
+ status: z.ZodEnum<{
20
+ DRAFT: "DRAFT";
21
+ POSTED: "POSTED";
22
+ }>;
23
+ currency: z.ZodString;
24
+ externalId: z.ZodOptional<z.ZodString>;
25
+ totalDebit: z.ZodObject<{
26
+ amount: z.ZodNumber;
27
+ currency: z.ZodString;
28
+ originalAmount: z.ZodOptional<z.ZodNumber>;
29
+ originalCurrency: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>;
31
+ totalCredit: z.ZodObject<{
32
+ amount: z.ZodNumber;
33
+ currency: z.ZodString;
34
+ originalAmount: z.ZodOptional<z.ZodNumber>;
35
+ originalCurrency: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>;
37
+ lines: z.ZodArray<z.ZodObject<{
38
+ lineNumber: z.ZodNumber;
39
+ account: z.ZodString;
40
+ debit: z.ZodObject<{
41
+ amount: z.ZodNumber;
42
+ currency: z.ZodString;
43
+ originalAmount: z.ZodOptional<z.ZodNumber>;
44
+ originalCurrency: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>;
46
+ credit: z.ZodObject<{
47
+ amount: z.ZodNumber;
48
+ currency: z.ZodString;
49
+ originalAmount: z.ZodOptional<z.ZodNumber>;
50
+ originalCurrency: z.ZodOptional<z.ZodString>;
51
+ }, z.core.$strip>;
52
+ memo: z.ZodOptional<z.ZodString>;
53
+ taxCode: z.ZodOptional<z.ZodString>;
54
+ costCenter: z.ZodOptional<z.ZodString>;
55
+ ledgerAccountName: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>>;
57
+ postedAt: z.ZodOptional<z.ZodString>;
58
+ errorMessage: z.ZodOptional<z.ZodString>;
59
+ postingCheckpoint: z.ZodOptional<z.ZodString>;
60
+ voucherNumber: z.ZodOptional<z.ZodNumber>;
61
+ voucherSeriesCode: z.ZodOptional<z.ZodString>;
62
+ fortnoxFileId: z.ZodOptional<z.ZodString>;
63
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
64
+ fortnox: "fortnox";
65
+ bokio: "bokio";
66
+ ledgit: "ledgit";
67
+ }>>;
68
+ sourceSyncedAt: z.ZodOptional<z.ZodString>;
69
+ reversingEntryExternalId: z.ZodOptional<z.ZodString>;
70
+ reversedByEntryExternalId: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strip>;
72
+ export declare const DocumentSchema: z.ZodObject<{
73
+ kind: z.ZodEnum<{
74
+ RECEIPT: "RECEIPT";
75
+ SUPPLIER_INVOICE: "SUPPLIER_INVOICE";
76
+ CUSTOMER_INVOICE: "CUSTOMER_INVOICE";
77
+ TRAKTAMENTE: "TRAKTAMENTE";
78
+ EMAIL: "EMAIL";
79
+ OTHER: "OTHER";
80
+ }>;
81
+ status: z.ZodEnum<{
82
+ DRAFT: "DRAFT";
83
+ POSTED: "POSTED";
84
+ REVIEWED: "REVIEWED";
85
+ READY_TO_EXPORT: "READY_TO_EXPORT";
86
+ EXPORTED: "EXPORTED";
87
+ ERROR: "ERROR";
88
+ DISCARDED: "DISCARDED";
89
+ }>;
90
+ fileName: z.ZodString;
91
+ mimeType: z.ZodString;
92
+ documentDate: z.ZodOptional<z.ZodString>;
93
+ documentNumber: z.ZodOptional<z.ZodString>;
94
+ description: z.ZodOptional<z.ZodString>;
95
+ counterparty: z.ZodOptional<z.ZodString>;
96
+ totalAmount: z.ZodOptional<z.ZodObject<{
97
+ amount: z.ZodString;
98
+ currency: z.ZodString;
99
+ }, z.core.$strip>>;
100
+ totalTaxAmount: z.ZodOptional<z.ZodObject<{
101
+ amount: z.ZodString;
102
+ currency: z.ZodString;
103
+ }, z.core.$strip>>;
104
+ subTotal: z.ZodOptional<z.ZodObject<{
105
+ amount: z.ZodString;
106
+ currency: z.ZodString;
107
+ }, z.core.$strip>>;
108
+ taxDetails: z.ZodOptional<z.ZodArray<z.ZodObject<{
109
+ rate: z.ZodNumber;
110
+ amount: z.ZodString;
111
+ description: z.ZodOptional<z.ZodString>;
112
+ }, z.core.$strip>>>;
113
+ dueDate: z.ZodOptional<z.ZodString>;
114
+ currencyRate: z.ZodOptional<z.ZodNumber>;
115
+ vendorTaxId: z.ZodOptional<z.ZodString>;
116
+ interpretationError: z.ZodOptional<z.ZodString>;
117
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
118
+ fortnox: "fortnox";
119
+ bokio: "bokio";
120
+ ledgit: "ledgit";
121
+ }>>;
122
+ sourceId: z.ZodOptional<z.ZodString>;
123
+ uploadedAt: z.ZodOptional<z.ZodString>;
124
+ interpretedAt: z.ZodOptional<z.ZodString>;
125
+ senderEmail: z.ZodOptional<z.ZodString>;
126
+ senderName: z.ZodOptional<z.ZodString>;
127
+ emailSubject: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$strip>;
129
+ export declare const FiscalYearSchema: z.ZodObject<{
130
+ name: z.ZodString;
131
+ startDate: z.ZodString;
132
+ endDate: z.ZodString;
133
+ status: z.ZodEnum<{
134
+ OPEN: "OPEN";
135
+ CLOSED: "CLOSED";
136
+ }>;
137
+ externalId: z.ZodOptional<z.ZodString>;
138
+ }, z.core.$strip>;
139
+ export declare const LedgerAccountSchema: z.ZodObject<{
140
+ code: z.ZodString;
141
+ name: z.ZodString;
142
+ description: z.ZodOptional<z.ZodString>;
143
+ }, z.core.$strip>;
144
+ export declare const CompanyInfoSchema: z.ZodObject<{
145
+ id: z.ZodString;
146
+ name: z.ZodString;
147
+ organizationNumber: z.ZodOptional<z.ZodString>;
148
+ address: z.ZodOptional<z.ZodObject<{
149
+ street: z.ZodOptional<z.ZodString>;
150
+ zipCode: z.ZodOptional<z.ZodString>;
151
+ city: z.ZodOptional<z.ZodString>;
152
+ country: z.ZodOptional<z.ZodString>;
153
+ }, z.core.$strip>>;
154
+ inboxEmail: z.ZodOptional<z.ZodString>;
155
+ inboxEmailEnabled: z.ZodOptional<z.ZodBoolean>;
156
+ }, z.core.$strip>;
157
+ export declare const CompanyWithInboxSchema: z.ZodObject<{
158
+ id: z.ZodString;
159
+ name: z.ZodString;
160
+ organizationNumber: z.ZodOptional<z.ZodString>;
161
+ inboxEmail: z.ZodString;
162
+ inboxEmailEnabled: z.ZodBoolean;
163
+ }, z.core.$strip>;
164
+ export declare const CompanyInfoResponseSchema: z.ZodObject<{
165
+ data: z.ZodObject<{
166
+ id: z.ZodString;
167
+ name: z.ZodString;
168
+ organizationNumber: z.ZodOptional<z.ZodString>;
169
+ address: z.ZodOptional<z.ZodObject<{
170
+ street: z.ZodOptional<z.ZodString>;
171
+ zipCode: z.ZodOptional<z.ZodString>;
172
+ city: z.ZodOptional<z.ZodString>;
173
+ country: z.ZodOptional<z.ZodString>;
174
+ }, z.core.$strip>>;
175
+ inboxEmail: z.ZodOptional<z.ZodString>;
176
+ inboxEmailEnabled: z.ZodOptional<z.ZodBoolean>;
177
+ }, z.core.$strip>;
178
+ success: z.ZodBoolean;
179
+ }, z.core.$strip>;
180
+ export declare const CreateCompanyResponseSchema: z.ZodObject<{
181
+ data: z.ZodObject<{
182
+ id: z.ZodString;
183
+ name: z.ZodString;
184
+ organizationNumber: z.ZodOptional<z.ZodString>;
185
+ inboxEmail: z.ZodString;
186
+ inboxEmailEnabled: z.ZodBoolean;
187
+ }, z.core.$strip>;
188
+ success: z.ZodBoolean;
189
+ }, z.core.$strip>;
190
+ export declare const JournalEntriesResponseSchema: z.ZodObject<{
191
+ data: z.ZodArray<z.ZodObject<{
192
+ id: z.ZodOptional<z.ZodString>;
193
+ series: z.ZodOptional<z.ZodEnum<{
194
+ A: "A";
195
+ B: "B";
196
+ C: "C";
197
+ D: "D";
198
+ E: "E";
199
+ I: "I";
200
+ M: "M";
201
+ }>>;
202
+ entryNumber: z.ZodNumber;
203
+ entryDate: z.ZodString;
204
+ description: z.ZodString;
205
+ status: z.ZodEnum<{
206
+ DRAFT: "DRAFT";
207
+ POSTED: "POSTED";
208
+ }>;
209
+ currency: z.ZodString;
210
+ externalId: z.ZodOptional<z.ZodString>;
211
+ totalDebit: z.ZodObject<{
212
+ amount: z.ZodNumber;
213
+ currency: z.ZodString;
214
+ originalAmount: z.ZodOptional<z.ZodNumber>;
215
+ originalCurrency: z.ZodOptional<z.ZodString>;
216
+ }, z.core.$strip>;
217
+ totalCredit: z.ZodObject<{
218
+ amount: z.ZodNumber;
219
+ currency: z.ZodString;
220
+ originalAmount: z.ZodOptional<z.ZodNumber>;
221
+ originalCurrency: z.ZodOptional<z.ZodString>;
222
+ }, z.core.$strip>;
223
+ lines: z.ZodArray<z.ZodObject<{
224
+ lineNumber: z.ZodNumber;
225
+ account: z.ZodString;
226
+ debit: z.ZodObject<{
227
+ amount: z.ZodNumber;
228
+ currency: z.ZodString;
229
+ originalAmount: z.ZodOptional<z.ZodNumber>;
230
+ originalCurrency: z.ZodOptional<z.ZodString>;
231
+ }, z.core.$strip>;
232
+ credit: z.ZodObject<{
233
+ amount: z.ZodNumber;
234
+ currency: z.ZodString;
235
+ originalAmount: z.ZodOptional<z.ZodNumber>;
236
+ originalCurrency: z.ZodOptional<z.ZodString>;
237
+ }, z.core.$strip>;
238
+ memo: z.ZodOptional<z.ZodString>;
239
+ taxCode: z.ZodOptional<z.ZodString>;
240
+ costCenter: z.ZodOptional<z.ZodString>;
241
+ ledgerAccountName: z.ZodOptional<z.ZodString>;
242
+ }, z.core.$strip>>;
243
+ postedAt: z.ZodOptional<z.ZodString>;
244
+ errorMessage: z.ZodOptional<z.ZodString>;
245
+ postingCheckpoint: z.ZodOptional<z.ZodString>;
246
+ voucherNumber: z.ZodOptional<z.ZodNumber>;
247
+ voucherSeriesCode: z.ZodOptional<z.ZodString>;
248
+ fortnoxFileId: z.ZodOptional<z.ZodString>;
249
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
250
+ fortnox: "fortnox";
251
+ bokio: "bokio";
252
+ ledgit: "ledgit";
253
+ }>>;
254
+ sourceSyncedAt: z.ZodOptional<z.ZodString>;
255
+ reversingEntryExternalId: z.ZodOptional<z.ZodString>;
256
+ reversedByEntryExternalId: z.ZodOptional<z.ZodString>;
257
+ }, z.core.$strip>>;
258
+ pagination: z.ZodObject<{
259
+ page: z.ZodNumber;
260
+ pageSize: z.ZodNumber;
261
+ totalItems: z.ZodNumber;
262
+ totalPages: z.ZodNumber;
263
+ }, z.core.$strip>;
264
+ success: z.ZodBoolean;
265
+ }, z.core.$strip>;
266
+ export declare const JournalEntryResponseSchema: z.ZodObject<{
267
+ data: z.ZodObject<{
268
+ id: z.ZodOptional<z.ZodString>;
269
+ series: z.ZodOptional<z.ZodEnum<{
270
+ A: "A";
271
+ B: "B";
272
+ C: "C";
273
+ D: "D";
274
+ E: "E";
275
+ I: "I";
276
+ M: "M";
277
+ }>>;
278
+ entryNumber: z.ZodNumber;
279
+ entryDate: z.ZodString;
280
+ description: z.ZodString;
281
+ status: z.ZodEnum<{
282
+ DRAFT: "DRAFT";
283
+ POSTED: "POSTED";
284
+ }>;
285
+ currency: z.ZodString;
286
+ externalId: z.ZodOptional<z.ZodString>;
287
+ totalDebit: z.ZodObject<{
288
+ amount: z.ZodNumber;
289
+ currency: z.ZodString;
290
+ originalAmount: z.ZodOptional<z.ZodNumber>;
291
+ originalCurrency: z.ZodOptional<z.ZodString>;
292
+ }, z.core.$strip>;
293
+ totalCredit: z.ZodObject<{
294
+ amount: z.ZodNumber;
295
+ currency: z.ZodString;
296
+ originalAmount: z.ZodOptional<z.ZodNumber>;
297
+ originalCurrency: z.ZodOptional<z.ZodString>;
298
+ }, z.core.$strip>;
299
+ lines: z.ZodArray<z.ZodObject<{
300
+ lineNumber: z.ZodNumber;
301
+ account: z.ZodString;
302
+ debit: z.ZodObject<{
303
+ amount: z.ZodNumber;
304
+ currency: z.ZodString;
305
+ originalAmount: z.ZodOptional<z.ZodNumber>;
306
+ originalCurrency: z.ZodOptional<z.ZodString>;
307
+ }, z.core.$strip>;
308
+ credit: z.ZodObject<{
309
+ amount: z.ZodNumber;
310
+ currency: z.ZodString;
311
+ originalAmount: z.ZodOptional<z.ZodNumber>;
312
+ originalCurrency: z.ZodOptional<z.ZodString>;
313
+ }, z.core.$strip>;
314
+ memo: z.ZodOptional<z.ZodString>;
315
+ taxCode: z.ZodOptional<z.ZodString>;
316
+ costCenter: z.ZodOptional<z.ZodString>;
317
+ ledgerAccountName: z.ZodOptional<z.ZodString>;
318
+ }, z.core.$strip>>;
319
+ postedAt: z.ZodOptional<z.ZodString>;
320
+ errorMessage: z.ZodOptional<z.ZodString>;
321
+ postingCheckpoint: z.ZodOptional<z.ZodString>;
322
+ voucherNumber: z.ZodOptional<z.ZodNumber>;
323
+ voucherSeriesCode: z.ZodOptional<z.ZodString>;
324
+ fortnoxFileId: z.ZodOptional<z.ZodString>;
325
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
326
+ fortnox: "fortnox";
327
+ bokio: "bokio";
328
+ ledgit: "ledgit";
329
+ }>>;
330
+ sourceSyncedAt: z.ZodOptional<z.ZodString>;
331
+ reversingEntryExternalId: z.ZodOptional<z.ZodString>;
332
+ reversedByEntryExternalId: z.ZodOptional<z.ZodString>;
333
+ }, z.core.$strip>;
334
+ success: z.ZodBoolean;
335
+ }, z.core.$strip>;
336
+ export declare const DocumentsResponseSchema: z.ZodObject<{
337
+ data: z.ZodArray<z.ZodObject<{
338
+ kind: z.ZodEnum<{
339
+ RECEIPT: "RECEIPT";
340
+ SUPPLIER_INVOICE: "SUPPLIER_INVOICE";
341
+ CUSTOMER_INVOICE: "CUSTOMER_INVOICE";
342
+ TRAKTAMENTE: "TRAKTAMENTE";
343
+ EMAIL: "EMAIL";
344
+ OTHER: "OTHER";
345
+ }>;
346
+ status: z.ZodEnum<{
347
+ DRAFT: "DRAFT";
348
+ POSTED: "POSTED";
349
+ REVIEWED: "REVIEWED";
350
+ READY_TO_EXPORT: "READY_TO_EXPORT";
351
+ EXPORTED: "EXPORTED";
352
+ ERROR: "ERROR";
353
+ DISCARDED: "DISCARDED";
354
+ }>;
355
+ fileName: z.ZodString;
356
+ mimeType: z.ZodString;
357
+ documentDate: z.ZodOptional<z.ZodString>;
358
+ documentNumber: z.ZodOptional<z.ZodString>;
359
+ description: z.ZodOptional<z.ZodString>;
360
+ counterparty: z.ZodOptional<z.ZodString>;
361
+ totalAmount: z.ZodOptional<z.ZodObject<{
362
+ amount: z.ZodString;
363
+ currency: z.ZodString;
364
+ }, z.core.$strip>>;
365
+ totalTaxAmount: z.ZodOptional<z.ZodObject<{
366
+ amount: z.ZodString;
367
+ currency: z.ZodString;
368
+ }, z.core.$strip>>;
369
+ subTotal: z.ZodOptional<z.ZodObject<{
370
+ amount: z.ZodString;
371
+ currency: z.ZodString;
372
+ }, z.core.$strip>>;
373
+ taxDetails: z.ZodOptional<z.ZodArray<z.ZodObject<{
374
+ rate: z.ZodNumber;
375
+ amount: z.ZodString;
376
+ description: z.ZodOptional<z.ZodString>;
377
+ }, z.core.$strip>>>;
378
+ dueDate: z.ZodOptional<z.ZodString>;
379
+ currencyRate: z.ZodOptional<z.ZodNumber>;
380
+ vendorTaxId: z.ZodOptional<z.ZodString>;
381
+ interpretationError: z.ZodOptional<z.ZodString>;
382
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
383
+ fortnox: "fortnox";
384
+ bokio: "bokio";
385
+ ledgit: "ledgit";
386
+ }>>;
387
+ sourceId: z.ZodOptional<z.ZodString>;
388
+ uploadedAt: z.ZodOptional<z.ZodString>;
389
+ interpretedAt: z.ZodOptional<z.ZodString>;
390
+ senderEmail: z.ZodOptional<z.ZodString>;
391
+ senderName: z.ZodOptional<z.ZodString>;
392
+ emailSubject: z.ZodOptional<z.ZodString>;
393
+ }, z.core.$strip>>;
394
+ pagination: z.ZodObject<{
395
+ page: z.ZodNumber;
396
+ pageSize: z.ZodNumber;
397
+ totalItems: z.ZodNumber;
398
+ totalPages: z.ZodNumber;
399
+ }, z.core.$strip>;
400
+ success: z.ZodBoolean;
401
+ }, z.core.$strip>;
402
+ export declare const DocumentResponseSchema: z.ZodObject<{
403
+ data: z.ZodObject<{
404
+ kind: z.ZodEnum<{
405
+ RECEIPT: "RECEIPT";
406
+ SUPPLIER_INVOICE: "SUPPLIER_INVOICE";
407
+ CUSTOMER_INVOICE: "CUSTOMER_INVOICE";
408
+ TRAKTAMENTE: "TRAKTAMENTE";
409
+ EMAIL: "EMAIL";
410
+ OTHER: "OTHER";
411
+ }>;
412
+ status: z.ZodEnum<{
413
+ DRAFT: "DRAFT";
414
+ POSTED: "POSTED";
415
+ REVIEWED: "REVIEWED";
416
+ READY_TO_EXPORT: "READY_TO_EXPORT";
417
+ EXPORTED: "EXPORTED";
418
+ ERROR: "ERROR";
419
+ DISCARDED: "DISCARDED";
420
+ }>;
421
+ fileName: z.ZodString;
422
+ mimeType: z.ZodString;
423
+ documentDate: z.ZodOptional<z.ZodString>;
424
+ documentNumber: z.ZodOptional<z.ZodString>;
425
+ description: z.ZodOptional<z.ZodString>;
426
+ counterparty: z.ZodOptional<z.ZodString>;
427
+ totalAmount: z.ZodOptional<z.ZodObject<{
428
+ amount: z.ZodString;
429
+ currency: z.ZodString;
430
+ }, z.core.$strip>>;
431
+ totalTaxAmount: z.ZodOptional<z.ZodObject<{
432
+ amount: z.ZodString;
433
+ currency: z.ZodString;
434
+ }, z.core.$strip>>;
435
+ subTotal: z.ZodOptional<z.ZodObject<{
436
+ amount: z.ZodString;
437
+ currency: z.ZodString;
438
+ }, z.core.$strip>>;
439
+ taxDetails: z.ZodOptional<z.ZodArray<z.ZodObject<{
440
+ rate: z.ZodNumber;
441
+ amount: z.ZodString;
442
+ description: z.ZodOptional<z.ZodString>;
443
+ }, z.core.$strip>>>;
444
+ dueDate: z.ZodOptional<z.ZodString>;
445
+ currencyRate: z.ZodOptional<z.ZodNumber>;
446
+ vendorTaxId: z.ZodOptional<z.ZodString>;
447
+ interpretationError: z.ZodOptional<z.ZodString>;
448
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
449
+ fortnox: "fortnox";
450
+ bokio: "bokio";
451
+ ledgit: "ledgit";
452
+ }>>;
453
+ sourceId: z.ZodOptional<z.ZodString>;
454
+ uploadedAt: z.ZodOptional<z.ZodString>;
455
+ interpretedAt: z.ZodOptional<z.ZodString>;
456
+ senderEmail: z.ZodOptional<z.ZodString>;
457
+ senderName: z.ZodOptional<z.ZodString>;
458
+ emailSubject: z.ZodOptional<z.ZodString>;
459
+ }, z.core.$strip>;
460
+ success: z.ZodBoolean;
461
+ }, z.core.$strip>;
462
+ export declare const FiscalYearsResponseSchema: z.ZodObject<{
463
+ data: z.ZodArray<z.ZodObject<{
464
+ name: z.ZodString;
465
+ startDate: z.ZodString;
466
+ endDate: z.ZodString;
467
+ status: z.ZodEnum<{
468
+ OPEN: "OPEN";
469
+ CLOSED: "CLOSED";
470
+ }>;
471
+ externalId: z.ZodOptional<z.ZodString>;
472
+ }, z.core.$strip>>;
473
+ success: z.ZodBoolean;
474
+ }, z.core.$strip>;
475
+ export declare const LedgerAccountsResponseSchema: z.ZodObject<{
476
+ data: z.ZodArray<z.ZodObject<{
477
+ code: z.ZodString;
478
+ name: z.ZodString;
479
+ description: z.ZodOptional<z.ZodString>;
480
+ }, z.core.$strip>>;
481
+ success: z.ZodBoolean;
482
+ }, z.core.$strip>;
483
+ export declare const InboxItemSchema: z.ZodObject<{
484
+ id: z.ZodString;
485
+ documents: z.ZodArray<z.ZodObject<{
486
+ kind: z.ZodEnum<{
487
+ RECEIPT: "RECEIPT";
488
+ SUPPLIER_INVOICE: "SUPPLIER_INVOICE";
489
+ CUSTOMER_INVOICE: "CUSTOMER_INVOICE";
490
+ TRAKTAMENTE: "TRAKTAMENTE";
491
+ EMAIL: "EMAIL";
492
+ OTHER: "OTHER";
493
+ }>;
494
+ status: z.ZodEnum<{
495
+ DRAFT: "DRAFT";
496
+ POSTED: "POSTED";
497
+ REVIEWED: "REVIEWED";
498
+ READY_TO_EXPORT: "READY_TO_EXPORT";
499
+ EXPORTED: "EXPORTED";
500
+ ERROR: "ERROR";
501
+ DISCARDED: "DISCARDED";
502
+ }>;
503
+ fileName: z.ZodString;
504
+ mimeType: z.ZodString;
505
+ documentDate: z.ZodOptional<z.ZodString>;
506
+ documentNumber: z.ZodOptional<z.ZodString>;
507
+ description: z.ZodOptional<z.ZodString>;
508
+ counterparty: z.ZodOptional<z.ZodString>;
509
+ totalAmount: z.ZodOptional<z.ZodObject<{
510
+ amount: z.ZodString;
511
+ currency: z.ZodString;
512
+ }, z.core.$strip>>;
513
+ totalTaxAmount: z.ZodOptional<z.ZodObject<{
514
+ amount: z.ZodString;
515
+ currency: z.ZodString;
516
+ }, z.core.$strip>>;
517
+ subTotal: z.ZodOptional<z.ZodObject<{
518
+ amount: z.ZodString;
519
+ currency: z.ZodString;
520
+ }, z.core.$strip>>;
521
+ taxDetails: z.ZodOptional<z.ZodArray<z.ZodObject<{
522
+ rate: z.ZodNumber;
523
+ amount: z.ZodString;
524
+ description: z.ZodOptional<z.ZodString>;
525
+ }, z.core.$strip>>>;
526
+ dueDate: z.ZodOptional<z.ZodString>;
527
+ currencyRate: z.ZodOptional<z.ZodNumber>;
528
+ vendorTaxId: z.ZodOptional<z.ZodString>;
529
+ interpretationError: z.ZodOptional<z.ZodString>;
530
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
531
+ fortnox: "fortnox";
532
+ bokio: "bokio";
533
+ ledgit: "ledgit";
534
+ }>>;
535
+ sourceId: z.ZodOptional<z.ZodString>;
536
+ uploadedAt: z.ZodOptional<z.ZodString>;
537
+ interpretedAt: z.ZodOptional<z.ZodString>;
538
+ senderEmail: z.ZodOptional<z.ZodString>;
539
+ senderName: z.ZodOptional<z.ZodString>;
540
+ emailSubject: z.ZodOptional<z.ZodString>;
541
+ }, z.core.$strip>>;
542
+ }, z.core.$strip>;
543
+ export declare const InboxResponseSchema: z.ZodObject<{
544
+ data: z.ZodArray<z.ZodObject<{
545
+ id: z.ZodString;
546
+ documents: z.ZodArray<z.ZodObject<{
547
+ kind: z.ZodEnum<{
548
+ RECEIPT: "RECEIPT";
549
+ SUPPLIER_INVOICE: "SUPPLIER_INVOICE";
550
+ CUSTOMER_INVOICE: "CUSTOMER_INVOICE";
551
+ TRAKTAMENTE: "TRAKTAMENTE";
552
+ EMAIL: "EMAIL";
553
+ OTHER: "OTHER";
554
+ }>;
555
+ status: z.ZodEnum<{
556
+ DRAFT: "DRAFT";
557
+ POSTED: "POSTED";
558
+ REVIEWED: "REVIEWED";
559
+ READY_TO_EXPORT: "READY_TO_EXPORT";
560
+ EXPORTED: "EXPORTED";
561
+ ERROR: "ERROR";
562
+ DISCARDED: "DISCARDED";
563
+ }>;
564
+ fileName: z.ZodString;
565
+ mimeType: z.ZodString;
566
+ documentDate: z.ZodOptional<z.ZodString>;
567
+ documentNumber: z.ZodOptional<z.ZodString>;
568
+ description: z.ZodOptional<z.ZodString>;
569
+ counterparty: z.ZodOptional<z.ZodString>;
570
+ totalAmount: z.ZodOptional<z.ZodObject<{
571
+ amount: z.ZodString;
572
+ currency: z.ZodString;
573
+ }, z.core.$strip>>;
574
+ totalTaxAmount: z.ZodOptional<z.ZodObject<{
575
+ amount: z.ZodString;
576
+ currency: z.ZodString;
577
+ }, z.core.$strip>>;
578
+ subTotal: z.ZodOptional<z.ZodObject<{
579
+ amount: z.ZodString;
580
+ currency: z.ZodString;
581
+ }, z.core.$strip>>;
582
+ taxDetails: z.ZodOptional<z.ZodArray<z.ZodObject<{
583
+ rate: z.ZodNumber;
584
+ amount: z.ZodString;
585
+ description: z.ZodOptional<z.ZodString>;
586
+ }, z.core.$strip>>>;
587
+ dueDate: z.ZodOptional<z.ZodString>;
588
+ currencyRate: z.ZodOptional<z.ZodNumber>;
589
+ vendorTaxId: z.ZodOptional<z.ZodString>;
590
+ interpretationError: z.ZodOptional<z.ZodString>;
591
+ sourceIntegration: z.ZodOptional<z.ZodEnum<{
592
+ fortnox: "fortnox";
593
+ bokio: "bokio";
594
+ ledgit: "ledgit";
595
+ }>>;
596
+ sourceId: z.ZodOptional<z.ZodString>;
597
+ uploadedAt: z.ZodOptional<z.ZodString>;
598
+ interpretedAt: z.ZodOptional<z.ZodString>;
599
+ senderEmail: z.ZodOptional<z.ZodString>;
600
+ senderName: z.ZodOptional<z.ZodString>;
601
+ emailSubject: z.ZodOptional<z.ZodString>;
602
+ }, z.core.$strip>>;
603
+ }, z.core.$strip>>;
604
+ success: z.ZodBoolean;
605
+ }, z.core.$strip>;
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Zod schemas for Ledgit API validation
3
+ */
4
+ import { z } from "zod";
5
+ // Money amount schema
6
+ const MoneyAmountSchema = z.object({
7
+ amount: z.number(),
8
+ currency: z.string(),
9
+ originalAmount: z.number().optional(),
10
+ originalCurrency: z.string().optional(),
11
+ });
12
+ // Journal line schema
13
+ const JournalLineSchema = z.object({
14
+ lineNumber: z.number(),
15
+ account: z.string(),
16
+ debit: MoneyAmountSchema,
17
+ credit: MoneyAmountSchema,
18
+ memo: z.string().optional(),
19
+ taxCode: z.string().optional(),
20
+ costCenter: z.string().optional(),
21
+ ledgerAccountName: z.string().optional(),
22
+ });
23
+ // Journal entry schema
24
+ export const JournalEntrySchema = z.object({
25
+ id: z.string().optional(),
26
+ series: z.enum(["A", "B", "C", "D", "E", "I", "M"]).optional(),
27
+ entryNumber: z.number(),
28
+ entryDate: z.string(),
29
+ description: z.string(),
30
+ status: z.enum(["DRAFT", "POSTED"]),
31
+ currency: z.string(),
32
+ externalId: z.string().optional(),
33
+ totalDebit: MoneyAmountSchema,
34
+ totalCredit: MoneyAmountSchema,
35
+ lines: z.array(JournalLineSchema),
36
+ postedAt: z.string().optional(),
37
+ errorMessage: z.string().optional(),
38
+ postingCheckpoint: z.string().optional(),
39
+ voucherNumber: z.number().optional(),
40
+ voucherSeriesCode: z.string().optional(),
41
+ fortnoxFileId: z.string().optional(),
42
+ sourceIntegration: z.enum(["fortnox", "bokio", "ledgit"]).optional(),
43
+ sourceSyncedAt: z.string().optional(),
44
+ reversingEntryExternalId: z.string().optional(),
45
+ reversedByEntryExternalId: z.string().optional(),
46
+ });
47
+ // Document money amount schema (string-based for precision)
48
+ const DocumentMoneyAmountSchema = z.object({
49
+ amount: z.string(),
50
+ currency: z.string(),
51
+ });
52
+ // Tax detail schema
53
+ const TaxDetailSchema = z.object({
54
+ rate: z.number(),
55
+ amount: z.string(),
56
+ description: z.string().optional(),
57
+ });
58
+ // Document schema
59
+ export const DocumentSchema = z.object({
60
+ kind: z.enum(["RECEIPT", "SUPPLIER_INVOICE", "CUSTOMER_INVOICE", "TRAKTAMENTE", "EMAIL", "OTHER"]),
61
+ status: z.enum(["DRAFT", "REVIEWED", "READY_TO_EXPORT", "EXPORTED", "ERROR", "DISCARDED", "POSTED"]),
62
+ fileName: z.string(),
63
+ mimeType: z.string(),
64
+ documentDate: z.string().optional(),
65
+ documentNumber: z.string().optional(),
66
+ description: z.string().optional(),
67
+ counterparty: z.string().optional(),
68
+ totalAmount: DocumentMoneyAmountSchema.optional(),
69
+ totalTaxAmount: DocumentMoneyAmountSchema.optional(),
70
+ subTotal: DocumentMoneyAmountSchema.optional(),
71
+ taxDetails: z.array(TaxDetailSchema).optional(),
72
+ dueDate: z.string().optional(),
73
+ currencyRate: z.number().optional(),
74
+ vendorTaxId: z.string().optional(),
75
+ interpretationError: z.string().optional(),
76
+ sourceIntegration: z.enum(["fortnox", "bokio", "ledgit"]).optional(),
77
+ sourceId: z.string().optional(),
78
+ uploadedAt: z.string().optional(),
79
+ interpretedAt: z.string().optional(),
80
+ // Email-specific fields
81
+ senderEmail: z.string().optional(),
82
+ senderName: z.string().optional(),
83
+ emailSubject: z.string().optional(),
84
+ });
85
+ // Fiscal year schema
86
+ export const FiscalYearSchema = z.object({
87
+ name: z.string(),
88
+ startDate: z.string(),
89
+ endDate: z.string(),
90
+ status: z.enum(["OPEN", "CLOSED"]),
91
+ externalId: z.string().optional(),
92
+ });
93
+ // Ledger account schema
94
+ export const LedgerAccountSchema = z.object({
95
+ code: z.string(),
96
+ name: z.string(),
97
+ description: z.string().optional(),
98
+ });
99
+ // Company info schema
100
+ export const CompanyInfoSchema = z.object({
101
+ id: z.string(),
102
+ name: z.string(),
103
+ organizationNumber: z.string().optional(),
104
+ address: z
105
+ .object({
106
+ street: z.string().optional(),
107
+ zipCode: z.string().optional(),
108
+ city: z.string().optional(),
109
+ country: z.string().optional(),
110
+ })
111
+ .optional(),
112
+ inboxEmail: z.string().optional(),
113
+ inboxEmailEnabled: z.boolean().optional(),
114
+ });
115
+ // Company with inbox schema (for createCompany response)
116
+ export const CompanyWithInboxSchema = z.object({
117
+ id: z.string(),
118
+ name: z.string(),
119
+ organizationNumber: z.string().optional(),
120
+ inboxEmail: z.string(),
121
+ inboxEmailEnabled: z.boolean(),
122
+ });
123
+ // API response schemas
124
+ export const CompanyInfoResponseSchema = z.object({
125
+ data: CompanyInfoSchema,
126
+ success: z.boolean(),
127
+ });
128
+ export const CreateCompanyResponseSchema = z.object({
129
+ data: CompanyWithInboxSchema,
130
+ success: z.boolean(),
131
+ });
132
+ export const JournalEntriesResponseSchema = z.object({
133
+ data: z.array(JournalEntrySchema),
134
+ pagination: z.object({
135
+ page: z.number(),
136
+ pageSize: z.number(),
137
+ totalItems: z.number(),
138
+ totalPages: z.number(),
139
+ }),
140
+ success: z.boolean(),
141
+ });
142
+ export const JournalEntryResponseSchema = z.object({
143
+ data: JournalEntrySchema,
144
+ success: z.boolean(),
145
+ });
146
+ export const DocumentsResponseSchema = z.object({
147
+ data: z.array(DocumentSchema),
148
+ pagination: z.object({
149
+ page: z.number(),
150
+ pageSize: z.number(),
151
+ totalItems: z.number(),
152
+ totalPages: z.number(),
153
+ }),
154
+ success: z.boolean(),
155
+ });
156
+ export const DocumentResponseSchema = z.object({
157
+ data: DocumentSchema,
158
+ success: z.boolean(),
159
+ });
160
+ export const FiscalYearsResponseSchema = z.object({
161
+ data: z.array(FiscalYearSchema),
162
+ success: z.boolean(),
163
+ });
164
+ export const LedgerAccountsResponseSchema = z.object({
165
+ data: z.array(LedgerAccountSchema),
166
+ success: z.boolean(),
167
+ });
168
+ // Inbox item schema
169
+ export const InboxItemSchema = z.object({
170
+ id: z.string(),
171
+ documents: z.array(DocumentSchema),
172
+ });
173
+ // Inbox response schema
174
+ export const InboxResponseSchema = z.object({
175
+ data: z.array(InboxItemSchema),
176
+ success: z.boolean(),
177
+ });
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Ledgit API types
3
+ */
4
+ import type { JournalEntry, Document, FiscalYear, LedgerAccount } from "@moatless/bookkeeping-types";
5
+ export type { JournalEntry, Document, FiscalYear, LedgerAccount };
6
+ /**
7
+ * Client configuration
8
+ *
9
+ * Note: Company is derived from the JWT token, not configured here.
10
+ */
11
+ export interface LedgitClientConfig {
12
+ /**
13
+ * Function to get the current access token
14
+ */
15
+ getAccessToken: () => Promise<string>;
16
+ /**
17
+ * Optional custom base URL (overrides LEDGIT_CONFIG.API_BASE_URL)
18
+ */
19
+ baseUrl?: string;
20
+ /**
21
+ * Suppress console output
22
+ */
23
+ silent?: boolean;
24
+ }
25
+ /**
26
+ * Company information
27
+ */
28
+ export interface CompanyInfo {
29
+ id: string;
30
+ name: string;
31
+ organizationNumber?: string;
32
+ address?: {
33
+ street?: string;
34
+ zipCode?: string;
35
+ city?: string;
36
+ country?: string;
37
+ };
38
+ inboxEmail?: string;
39
+ inboxEmailEnabled?: boolean;
40
+ }
41
+ /**
42
+ * Company information with inbox email (returned from createCompany)
43
+ */
44
+ export interface CompanyWithInbox {
45
+ id: string;
46
+ name: string;
47
+ organizationNumber?: string;
48
+ inboxEmail: string;
49
+ inboxEmailEnabled: boolean;
50
+ }
51
+ /**
52
+ * Create company request
53
+ */
54
+ export interface CreateCompanyRequest {
55
+ name: string;
56
+ organizationNumber: string;
57
+ }
58
+ /**
59
+ * API response wrapper
60
+ */
61
+ export interface ApiResponse<T> {
62
+ data: T;
63
+ success: boolean;
64
+ }
65
+ /**
66
+ * Paginated API response
67
+ */
68
+ export interface PaginatedApiResponse<T> {
69
+ data: T[];
70
+ pagination: {
71
+ page: number;
72
+ pageSize: number;
73
+ totalItems: number;
74
+ totalPages: number;
75
+ };
76
+ success: boolean;
77
+ }
78
+ /**
79
+ * Create journal entry request
80
+ */
81
+ export interface CreateJournalEntryRequest {
82
+ series?: string;
83
+ entryNumber?: number;
84
+ entryDate: string;
85
+ description: string;
86
+ currency?: string;
87
+ lines: Array<{
88
+ lineNumber?: number;
89
+ account: string;
90
+ debit: {
91
+ amount: number;
92
+ currency: string;
93
+ };
94
+ credit: {
95
+ amount: number;
96
+ currency: string;
97
+ };
98
+ memo?: string;
99
+ taxCode?: string;
100
+ }>;
101
+ }
102
+ /**
103
+ * Document upload metadata
104
+ */
105
+ export interface DocumentUploadMetadata {
106
+ fileName: string;
107
+ mimeType?: string;
108
+ kind?: "RECEIPT" | "SUPPLIER_INVOICE" | "CUSTOMER_INVOICE" | "TRAKTAMENTE" | "OTHER";
109
+ description?: string;
110
+ documentDate?: string;
111
+ }
112
+ /**
113
+ * File upload options
114
+ */
115
+ export interface FileUploadOptions {
116
+ file: Blob | ArrayBuffer;
117
+ filename: string;
118
+ metadata?: DocumentUploadMetadata;
119
+ }
120
+ /**
121
+ * Inbox item with documents
122
+ */
123
+ export interface InboxItem {
124
+ id: string;
125
+ documents: Document[];
126
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@moatless/ledgit-client",
3
+ "version": "0.2.0",
4
+ "description": "API client for Ledgit bookkeeping service",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/aorwall/ledgit.git",
17
+ "directory": "packages/ledgit-client"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "type-check": "tsc --noEmit",
23
+ "test": "bun test",
24
+ "test:coverage": "bun test --coverage"
25
+ },
26
+ "dependencies": {
27
+ "@moatless/api-client": "workspace:*",
28
+ "@moatless/bookkeeping-types": "workspace:*",
29
+ "zod": "^4.1.13"
30
+ },
31
+ "devDependencies": {
32
+ "@types/bun": "latest",
33
+ "typescript": "^5.8.3"
34
+ }
35
+ }