timber-node 0.4.4 → 0.4.5
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/README.md +123 -123
- package/dist/company.d.ts +15 -1
- package/dist/customer.d.ts +1 -0
- package/dist/customer.js +50 -12
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/invoice.js +31 -34
- package/dist/{invoiceTemplates.d.ts → invoiceSettings.d.ts} +19 -19
- package/dist/{invoiceTemplates.js → invoiceSettings.js} +18 -18
- package/dist/taxRate.d.ts +24 -2
- package/dist/taxRate.js +22 -2
- package/dist/utils/convertToFormData.d.ts +8 -0
- package/dist/utils/convertToFormData.js +71 -0
- package/package.json +63 -63
package/README.md
CHANGED
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
# Timber SDK
|
|
2
|
-
|
|
3
|
-
Official Node.js SDK for integrating with the Timber accounting backend API.
|
|
4
|
-
|
|
5
|
-
Easily interact with Timber's core features like managing expenses, invoices, vendors, customers, payroll, and more using a unified SDK.
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install timber-node
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Getting Started
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
import { createClient } from 'timber-node';
|
|
17
|
-
|
|
18
|
-
const client = createClient('your-api-key', {
|
|
19
|
-
baseURL: 'https://api.timber.me', // optional
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// Example: List expenses
|
|
23
|
-
const expenses = await client.expense.list({ page: 1, limit: 10 });
|
|
24
|
-
console.log(expenses.data);
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Authentication
|
|
28
|
-
|
|
29
|
-
Timber uses API Key-based authentication. Generate this API key from your Timber profile developer settings.
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
const client = createClient('your-api-key');
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
You can also load your API key from environment variables using `dotenv`.
|
|
36
|
-
|
|
37
|
-
## SDK Structure
|
|
38
|
-
|
|
39
|
-
The SDK client exposes the following services:
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
client.expense;
|
|
43
|
-
client.expenseCategory;
|
|
44
|
-
client.rawExpense;
|
|
45
|
-
client.invoice;
|
|
46
|
-
client.invoicePayment;
|
|
47
|
-
client.vendorPayment;
|
|
48
|
-
client.billPayment;
|
|
49
|
-
client.customer;
|
|
50
|
-
client.taxRate;
|
|
51
|
-
client.salary;
|
|
52
|
-
client.employee;
|
|
53
|
-
client.bankStatement;
|
|
54
|
-
client.cheque;
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Each service provides common operations like `create`, `get`, `list`, `update`, and `delete` where applicable.
|
|
58
|
-
|
|
59
|
-
## Usage Examples
|
|
60
|
-
|
|
61
|
-
### Create an Expense
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
const response = await client.expense.create({
|
|
65
|
-
type: 'Travel',
|
|
66
|
-
merchant: 'Uber',
|
|
67
|
-
category: 'Transportation',
|
|
68
|
-
date: '2025-06-23',
|
|
69
|
-
payment_method: 'cash',
|
|
70
|
-
amount: 45.75,
|
|
71
|
-
});
|
|
72
|
-
console.log(response.data);
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### List Expenses
|
|
76
|
-
|
|
77
|
-
```typescript
|
|
78
|
-
const response = await client.expense.list({ page: 1, limit: 5 });
|
|
79
|
-
console.log(response.data);
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Update an Expense
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
const updates = { amount: 50.0 };
|
|
86
|
-
const response = await client.expense.update('expense_id_here', updates);
|
|
87
|
-
console.log(response.data);
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Delete an Expense
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
const response = await client.expense.delete('expense_id_here');
|
|
94
|
-
console.log(response.data.message);
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## TypeScript Support
|
|
98
|
-
|
|
99
|
-
The SDK includes full TypeScript support:
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
import type { Expense, CreateExpenseRequest } from 'timber-node';
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Error Handling
|
|
106
|
-
|
|
107
|
-
Errors are returned as Axios errors:
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
import axios from 'axios';
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
await client.expense.get('invalid-id');
|
|
114
|
-
} catch (err) {
|
|
115
|
-
if (axios.isAxiosError(err)) {
|
|
116
|
-
console.error(err.response?.status, err.response?.data);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Related Links
|
|
122
|
-
|
|
123
|
-
- [Timber Website](https://timber.me)
|
|
1
|
+
# Timber SDK
|
|
2
|
+
|
|
3
|
+
Official Node.js SDK for integrating with the Timber accounting backend API.
|
|
4
|
+
|
|
5
|
+
Easily interact with Timber's core features like managing expenses, invoices, vendors, customers, payroll, and more using a unified SDK.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install timber-node
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Getting Started
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createClient } from 'timber-node';
|
|
17
|
+
|
|
18
|
+
const client = createClient('your-api-key', {
|
|
19
|
+
baseURL: 'https://api.timber.me', // optional
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Example: List expenses
|
|
23
|
+
const expenses = await client.expense.list({ page: 1, limit: 10 });
|
|
24
|
+
console.log(expenses.data);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Authentication
|
|
28
|
+
|
|
29
|
+
Timber uses API Key-based authentication. Generate this API key from your Timber profile developer settings.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
const client = createClient('your-api-key');
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
You can also load your API key from environment variables using `dotenv`.
|
|
36
|
+
|
|
37
|
+
## SDK Structure
|
|
38
|
+
|
|
39
|
+
The SDK client exposes the following services:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
client.expense;
|
|
43
|
+
client.expenseCategory;
|
|
44
|
+
client.rawExpense;
|
|
45
|
+
client.invoice;
|
|
46
|
+
client.invoicePayment;
|
|
47
|
+
client.vendorPayment;
|
|
48
|
+
client.billPayment;
|
|
49
|
+
client.customer;
|
|
50
|
+
client.taxRate;
|
|
51
|
+
client.salary;
|
|
52
|
+
client.employee;
|
|
53
|
+
client.bankStatement;
|
|
54
|
+
client.cheque;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Each service provides common operations like `create`, `get`, `list`, `update`, and `delete` where applicable.
|
|
58
|
+
|
|
59
|
+
## Usage Examples
|
|
60
|
+
|
|
61
|
+
### Create an Expense
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const response = await client.expense.create({
|
|
65
|
+
type: 'Travel',
|
|
66
|
+
merchant: 'Uber',
|
|
67
|
+
category: 'Transportation',
|
|
68
|
+
date: '2025-06-23',
|
|
69
|
+
payment_method: 'cash',
|
|
70
|
+
amount: 45.75,
|
|
71
|
+
});
|
|
72
|
+
console.log(response.data);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### List Expenses
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const response = await client.expense.list({ page: 1, limit: 5 });
|
|
79
|
+
console.log(response.data);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Update an Expense
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
const updates = { amount: 50.0 };
|
|
86
|
+
const response = await client.expense.update('expense_id_here', updates);
|
|
87
|
+
console.log(response.data);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Delete an Expense
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const response = await client.expense.delete('expense_id_here');
|
|
94
|
+
console.log(response.data.message);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## TypeScript Support
|
|
98
|
+
|
|
99
|
+
The SDK includes full TypeScript support:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import type { Expense, CreateExpenseRequest } from 'timber-node';
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Error Handling
|
|
106
|
+
|
|
107
|
+
Errors are returned as Axios errors:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import axios from 'axios';
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
await client.expense.get('invalid-id');
|
|
114
|
+
} catch (err) {
|
|
115
|
+
if (axios.isAxiosError(err)) {
|
|
116
|
+
console.error(err.response?.status, err.response?.data);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Related Links
|
|
122
|
+
|
|
123
|
+
- [Timber Website](https://timber.me)
|
package/dist/company.d.ts
CHANGED
|
@@ -4,13 +4,26 @@ export interface CompanyData {
|
|
|
4
4
|
currency: string;
|
|
5
5
|
language: string;
|
|
6
6
|
address: string;
|
|
7
|
+
address_details: Map<string, any>;
|
|
7
8
|
city: string;
|
|
8
9
|
state: string;
|
|
9
10
|
zip_code: string;
|
|
10
|
-
country:
|
|
11
|
+
country: {
|
|
12
|
+
_id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
country_code: string;
|
|
15
|
+
currency: string;
|
|
16
|
+
timezone: string;
|
|
17
|
+
logo: string;
|
|
18
|
+
is_active: boolean;
|
|
19
|
+
created_at: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
};
|
|
11
22
|
email: string;
|
|
12
23
|
country_code: string;
|
|
13
24
|
mobile: string;
|
|
25
|
+
is_zakat: boolean;
|
|
26
|
+
zakat_number: string;
|
|
14
27
|
tax_number: string;
|
|
15
28
|
financial_start_date: string;
|
|
16
29
|
license_expiry: string;
|
|
@@ -25,6 +38,7 @@ export interface CompanyData {
|
|
|
25
38
|
license_number: string;
|
|
26
39
|
license_authority: string;
|
|
27
40
|
trn: string;
|
|
41
|
+
crn: string;
|
|
28
42
|
}
|
|
29
43
|
export interface Company extends CompanyData {
|
|
30
44
|
_id: string;
|
package/dist/customer.d.ts
CHANGED
package/dist/customer.js
CHANGED
|
@@ -46,17 +46,36 @@ class CustomerService {
|
|
|
46
46
|
*/
|
|
47
47
|
async create(data) {
|
|
48
48
|
const { formData, headers } = await (0, getFormData_1.getFormData)();
|
|
49
|
-
|
|
49
|
+
const appendFormData = (key, value) => {
|
|
50
|
+
if (value === undefined || value === null)
|
|
51
|
+
return;
|
|
50
52
|
if (value instanceof File) {
|
|
51
53
|
formData.append(key, value);
|
|
54
|
+
return;
|
|
52
55
|
}
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
value.forEach((item, index) => {
|
|
58
|
+
if (item instanceof File) {
|
|
59
|
+
formData.append(key, item);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
appendFormData(`${key}[${index}]`, item);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
55
66
|
}
|
|
67
|
+
if (typeof value === 'object') {
|
|
68
|
+
Object.entries(value).forEach(([childKey, childValue]) => {
|
|
69
|
+
appendFormData(`${key}[${childKey}]`, childValue);
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
formData.append(key, String(value));
|
|
74
|
+
};
|
|
75
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
76
|
+
appendFormData(key, value);
|
|
56
77
|
});
|
|
57
|
-
return await this.http.post('/customer/customer', formData, {
|
|
58
|
-
headers,
|
|
59
|
-
});
|
|
78
|
+
return await this.http.post('/customer/customer', formData, { headers });
|
|
60
79
|
}
|
|
61
80
|
/**
|
|
62
81
|
* Update an existing customer.
|
|
@@ -74,17 +93,36 @@ class CustomerService {
|
|
|
74
93
|
*/
|
|
75
94
|
async update(id, data) {
|
|
76
95
|
const { formData, headers } = await (0, getFormData_1.getFormData)();
|
|
77
|
-
|
|
96
|
+
const appendFormData = (key, value) => {
|
|
97
|
+
if (value === undefined || value === null)
|
|
98
|
+
return;
|
|
78
99
|
if (value instanceof File) {
|
|
79
100
|
formData.append(key, value);
|
|
101
|
+
return;
|
|
80
102
|
}
|
|
81
|
-
|
|
82
|
-
|
|
103
|
+
if (Array.isArray(value)) {
|
|
104
|
+
value.forEach((item, index) => {
|
|
105
|
+
if (item instanceof File) {
|
|
106
|
+
formData.append(key, item);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
appendFormData(`${key}[${index}]`, item);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
83
113
|
}
|
|
114
|
+
if (typeof value === 'object') {
|
|
115
|
+
Object.entries(value).forEach(([childKey, childValue]) => {
|
|
116
|
+
appendFormData(`${key}[${childKey}]`, childValue);
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
formData.append(key, String(value));
|
|
121
|
+
};
|
|
122
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
123
|
+
appendFormData(key, value);
|
|
84
124
|
});
|
|
85
|
-
return await this.http.put(`/customer/customer/${id}`, formData, {
|
|
86
|
-
headers,
|
|
87
|
-
});
|
|
125
|
+
return await this.http.put(`/customer/customer/${id}`, formData, { headers });
|
|
88
126
|
}
|
|
89
127
|
/**
|
|
90
128
|
* Delete an customer by ID.
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { ChequeService } from './cheque';
|
|
|
14
14
|
import { BankStatementService } from './bankStatement';
|
|
15
15
|
import { CompanyService } from './company';
|
|
16
16
|
import { InvoiceNumberService } from './invoiceNumber';
|
|
17
|
-
import {
|
|
17
|
+
import { InvoiceSettingsService } from './invoiceSettings';
|
|
18
18
|
import { InvoiceItemService } from './invoiceItem';
|
|
19
19
|
declare class TimberClient {
|
|
20
20
|
auth: AuthService;
|
|
@@ -33,7 +33,7 @@ declare class TimberClient {
|
|
|
33
33
|
bankStatement: BankStatementService;
|
|
34
34
|
company: CompanyService;
|
|
35
35
|
invoiceNumber: InvoiceNumberService;
|
|
36
|
-
|
|
36
|
+
invoiceSettings: InvoiceSettingsService;
|
|
37
37
|
invoiceItem: InvoiceItemService;
|
|
38
38
|
constructor(apiKey: string, options?: {
|
|
39
39
|
baseURL?: string;
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ const cheque_1 = require("./cheque");
|
|
|
21
21
|
const bankStatement_1 = require("./bankStatement");
|
|
22
22
|
const company_1 = require("./company");
|
|
23
23
|
const invoiceNumber_1 = require("./invoiceNumber");
|
|
24
|
-
const
|
|
24
|
+
const invoiceSettings_1 = require("./invoiceSettings");
|
|
25
25
|
const invoiceItem_1 = require("./invoiceItem");
|
|
26
26
|
class TimberClient {
|
|
27
27
|
constructor(apiKey, options = {}) {
|
|
@@ -60,7 +60,7 @@ class TimberClient {
|
|
|
60
60
|
this.bankStatement = new bankStatement_1.BankStatementService(http);
|
|
61
61
|
this.company = new company_1.CompanyService(http);
|
|
62
62
|
this.invoiceNumber = new invoiceNumber_1.InvoiceNumberService(http);
|
|
63
|
-
this.
|
|
63
|
+
this.invoiceSettings = new invoiceSettings_1.InvoiceSettingsService(http);
|
|
64
64
|
this.invoiceItem = new invoiceItem_1.InvoiceItemService(http);
|
|
65
65
|
}
|
|
66
66
|
}
|
package/dist/invoice.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InvoiceService = void 0;
|
|
4
4
|
const getFormData_1 = require("./utils/getFormData");
|
|
5
|
+
const convertToFormData_1 = require("./utils/convertToFormData");
|
|
5
6
|
/**
|
|
6
7
|
* Service for Invoice
|
|
7
8
|
*
|
|
@@ -49,45 +50,41 @@ class InvoiceService {
|
|
|
49
50
|
}
|
|
50
51
|
async create(data) {
|
|
51
52
|
const { formData, headers } = await (0, getFormData_1.getFormData)();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
return await this.http.post('/customer/invoice', formData, {
|
|
53
|
+
const formattedFormData = (0, convertToFormData_1.convertToFormData)(data, formData);
|
|
54
|
+
// for (const key in data) {
|
|
55
|
+
// const value = (data as any)[key];
|
|
56
|
+
// if (key === 'items' || key === 'customer' || key === 'biller') {
|
|
57
|
+
// formattedFormData.append(key, JSON.stringify(value));
|
|
58
|
+
// } else if (key === 'logo' && value && typeof value.pipe === 'function') {
|
|
59
|
+
// // This is a ReadStream
|
|
60
|
+
// formattedFormData.append('logo', value);
|
|
61
|
+
// } else if (value instanceof Date) {
|
|
62
|
+
// formattedFormData.append(key, value.toISOString());
|
|
63
|
+
// } else if (value !== undefined && value !== null) {
|
|
64
|
+
// formattedFormData.append(key, value.toString());
|
|
65
|
+
// }
|
|
66
|
+
// }
|
|
67
|
+
return await this.http.post('/customer/invoice', formattedFormData, {
|
|
69
68
|
headers,
|
|
70
69
|
});
|
|
71
70
|
}
|
|
72
71
|
async update(id, data) {
|
|
73
72
|
const { formData, headers } = await (0, getFormData_1.getFormData)();
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
return await this.http.put(`/customer/invoice/${id}`, data, {
|
|
73
|
+
const formattedFormData = (0, convertToFormData_1.convertToFormData)(data, formData);
|
|
74
|
+
// for (const key in data) {
|
|
75
|
+
// const value = (data as any)[key];
|
|
76
|
+
// if (key === 'items' || key === 'customer' || key === 'biller') {
|
|
77
|
+
// formattedFormData.append(key, JSON.stringify(value));
|
|
78
|
+
// } else if (key === 'logo' && value && typeof value.pipe === 'function') {
|
|
79
|
+
// // This is a ReadStream
|
|
80
|
+
// formattedFormData.append('logo', value);
|
|
81
|
+
// } else if (value instanceof Date) {
|
|
82
|
+
// formattedFormData.append(key, value.toISOString());
|
|
83
|
+
// } else if (value !== undefined && value !== null) {
|
|
84
|
+
// formattedFormData.append(key, value.toString());
|
|
85
|
+
// }
|
|
86
|
+
// }
|
|
87
|
+
return await this.http.put(`/customer/invoice/${id}`, formattedFormData, {
|
|
91
88
|
headers,
|
|
92
89
|
});
|
|
93
90
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AxiosInstance, AxiosResponse } from 'axios';
|
|
2
|
-
export interface
|
|
2
|
+
export interface CreateInvoiceSettingsRequest {
|
|
3
3
|
terms: [
|
|
4
4
|
{
|
|
5
5
|
name: string;
|
|
@@ -14,8 +14,8 @@ export interface CreateInvoiceTemplateRequest {
|
|
|
14
14
|
];
|
|
15
15
|
type?: 'terms' | 'notes';
|
|
16
16
|
}
|
|
17
|
-
export type
|
|
18
|
-
export interface
|
|
17
|
+
export type UpdateInvoiceSettingsRequest = Partial<CreateInvoiceSettingsRequest>;
|
|
18
|
+
export interface InvoiceSettings {
|
|
19
19
|
_id: string;
|
|
20
20
|
company: string;
|
|
21
21
|
terms: [
|
|
@@ -33,7 +33,7 @@ export interface InvoiceTemplate {
|
|
|
33
33
|
created_at: string;
|
|
34
34
|
updated_at: string;
|
|
35
35
|
}
|
|
36
|
-
export interface
|
|
36
|
+
export interface InvoiceSettingsQueryParams {
|
|
37
37
|
page?: number;
|
|
38
38
|
limit?: number;
|
|
39
39
|
sort?: string;
|
|
@@ -47,11 +47,11 @@ export interface InvoiceTemplateQueryParams {
|
|
|
47
47
|
* ```ts
|
|
48
48
|
* const { createClient } = require('timber-sdk-dev');
|
|
49
49
|
* const client = createClient('your-api-key');
|
|
50
|
-
* const
|
|
51
|
-
* console.log(
|
|
50
|
+
* const InvoiceSettings = await client.InvoiceSettings.list({ page: 1, limit: 10 });
|
|
51
|
+
* console.log(InvoiceSettings.data);
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
|
-
export declare class
|
|
54
|
+
export declare class InvoiceSettingsService {
|
|
55
55
|
private http;
|
|
56
56
|
constructor(http: AxiosInstance);
|
|
57
57
|
/**
|
|
@@ -61,11 +61,11 @@ export declare class InvoiceTemplateService {
|
|
|
61
61
|
*
|
|
62
62
|
* @example
|
|
63
63
|
* ```ts
|
|
64
|
-
* const
|
|
65
|
-
* console.log(
|
|
64
|
+
* const invoiceSettingss = await client.InvoiceSettings.list();
|
|
65
|
+
* console.log(invoiceSettingss.data);
|
|
66
66
|
* ```
|
|
67
67
|
*/
|
|
68
|
-
list(params:
|
|
68
|
+
list(params: InvoiceSettingsQueryParams): Promise<AxiosResponse<InvoiceSettings>>;
|
|
69
69
|
/**
|
|
70
70
|
* Fetch a single invoice template by ID.
|
|
71
71
|
*
|
|
@@ -74,10 +74,10 @@ export declare class InvoiceTemplateService {
|
|
|
74
74
|
*
|
|
75
75
|
* @example
|
|
76
76
|
* ```ts
|
|
77
|
-
* const
|
|
78
|
-
* console.log(
|
|
77
|
+
* const invoiceSettings = await client.InvoiceSettings.get('invoice_template_id_here');
|
|
78
|
+
* console.log(invoiceSettings.data);
|
|
79
79
|
* ``` */
|
|
80
|
-
get(id: string): Promise<AxiosResponse<
|
|
80
|
+
get(id: string): Promise<AxiosResponse<InvoiceSettings>>;
|
|
81
81
|
/**
|
|
82
82
|
* Create a new invoice template.
|
|
83
83
|
*
|
|
@@ -86,7 +86,7 @@ export declare class InvoiceTemplateService {
|
|
|
86
86
|
*
|
|
87
87
|
* @example
|
|
88
88
|
* ```ts
|
|
89
|
-
* const
|
|
89
|
+
* const newInvoiceSettings = {
|
|
90
90
|
* terms: [
|
|
91
91
|
* {
|
|
92
92
|
* name: "Terms",
|
|
@@ -100,11 +100,11 @@ export declare class InvoiceTemplateService {
|
|
|
100
100
|
* }
|
|
101
101
|
* ]
|
|
102
102
|
* };
|
|
103
|
-
* const response = await client.
|
|
103
|
+
* const response = await client.InvoiceSettings.create(newInvoiceSettings);
|
|
104
104
|
* console.log(response.data);
|
|
105
105
|
* ```
|
|
106
106
|
*/
|
|
107
|
-
create(data:
|
|
107
|
+
create(data: CreateInvoiceSettingsRequest): Promise<AxiosResponse<InvoiceSettings>>;
|
|
108
108
|
/**
|
|
109
109
|
* Update an existing invoice template.
|
|
110
110
|
*
|
|
@@ -120,11 +120,11 @@ export declare class InvoiceTemplateService {
|
|
|
120
120
|
* content: "Notes content"
|
|
121
121
|
* }
|
|
122
122
|
* ]};
|
|
123
|
-
* const updated = await client.
|
|
123
|
+
* const updated = await client.InvoiceSettings.update('invoice_template_id_here', updates);
|
|
124
124
|
* console.log(updated.data);
|
|
125
125
|
* ```
|
|
126
126
|
*/
|
|
127
|
-
update(id: string, data:
|
|
127
|
+
update(id: string, data: CreateInvoiceSettingsRequest): Promise<AxiosResponse<InvoiceSettings>>;
|
|
128
128
|
/**
|
|
129
129
|
* Delete an invoice template by ID.
|
|
130
130
|
*
|
|
@@ -133,7 +133,7 @@ export declare class InvoiceTemplateService {
|
|
|
133
133
|
*
|
|
134
134
|
* @example
|
|
135
135
|
* ```ts
|
|
136
|
-
* const response = await client.
|
|
136
|
+
* const response = await client.InvoiceSettings.delete('expense_category_id_here');
|
|
137
137
|
* console.log(response.data.message);
|
|
138
138
|
* ```
|
|
139
139
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.InvoiceSettingsService = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Service for Invoice Template
|
|
6
6
|
*
|
|
@@ -8,11 +8,11 @@ exports.InvoiceTemplateService = void 0;
|
|
|
8
8
|
* ```ts
|
|
9
9
|
* const { createClient } = require('timber-sdk-dev');
|
|
10
10
|
* const client = createClient('your-api-key');
|
|
11
|
-
* const
|
|
12
|
-
* console.log(
|
|
11
|
+
* const InvoiceSettings = await client.InvoiceSettings.list({ page: 1, limit: 10 });
|
|
12
|
+
* console.log(InvoiceSettings.data);
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
|
-
class
|
|
15
|
+
class InvoiceSettingsService {
|
|
16
16
|
constructor(http) {
|
|
17
17
|
this.http = http;
|
|
18
18
|
}
|
|
@@ -23,12 +23,12 @@ class InvoiceTemplateService {
|
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
25
25
|
* ```ts
|
|
26
|
-
* const
|
|
27
|
-
* console.log(
|
|
26
|
+
* const invoiceSettingss = await client.InvoiceSettings.list();
|
|
27
|
+
* console.log(invoiceSettingss.data);
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
async list(params) {
|
|
31
|
-
return await this.http.get('/customer/invoice-
|
|
31
|
+
return await this.http.get('/customer/invoice-settings', {
|
|
32
32
|
params,
|
|
33
33
|
});
|
|
34
34
|
}
|
|
@@ -40,11 +40,11 @@ class InvoiceTemplateService {
|
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```ts
|
|
43
|
-
* const
|
|
44
|
-
* console.log(
|
|
43
|
+
* const invoiceSettings = await client.InvoiceSettings.get('invoice_template_id_here');
|
|
44
|
+
* console.log(invoiceSettings.data);
|
|
45
45
|
* ``` */
|
|
46
46
|
async get(id) {
|
|
47
|
-
return await this.http.get(`/customer/invoice-
|
|
47
|
+
return await this.http.get(`/customer/invoice-settings/${id}`);
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Create a new invoice template.
|
|
@@ -54,7 +54,7 @@ class InvoiceTemplateService {
|
|
|
54
54
|
*
|
|
55
55
|
* @example
|
|
56
56
|
* ```ts
|
|
57
|
-
* const
|
|
57
|
+
* const newInvoiceSettings = {
|
|
58
58
|
* terms: [
|
|
59
59
|
* {
|
|
60
60
|
* name: "Terms",
|
|
@@ -68,12 +68,12 @@ class InvoiceTemplateService {
|
|
|
68
68
|
* }
|
|
69
69
|
* ]
|
|
70
70
|
* };
|
|
71
|
-
* const response = await client.
|
|
71
|
+
* const response = await client.InvoiceSettings.create(newInvoiceSettings);
|
|
72
72
|
* console.log(response.data);
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
75
|
async create(data) {
|
|
76
|
-
return await this.http.post('/customer/invoice-
|
|
76
|
+
return await this.http.post('/customer/invoice-settings', data);
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
79
|
* Update an existing invoice template.
|
|
@@ -90,12 +90,12 @@ class InvoiceTemplateService {
|
|
|
90
90
|
* content: "Notes content"
|
|
91
91
|
* }
|
|
92
92
|
* ]};
|
|
93
|
-
* const updated = await client.
|
|
93
|
+
* const updated = await client.InvoiceSettings.update('invoice_template_id_here', updates);
|
|
94
94
|
* console.log(updated.data);
|
|
95
95
|
* ```
|
|
96
96
|
*/
|
|
97
97
|
async update(id, data) {
|
|
98
|
-
return await this.http.put(`/customer/invoice-
|
|
98
|
+
return await this.http.put(`/customer/invoice-settings/${id}`, data);
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* Delete an invoice template by ID.
|
|
@@ -105,12 +105,12 @@ class InvoiceTemplateService {
|
|
|
105
105
|
*
|
|
106
106
|
* @example
|
|
107
107
|
* ```ts
|
|
108
|
-
* const response = await client.
|
|
108
|
+
* const response = await client.InvoiceSettings.delete('expense_category_id_here');
|
|
109
109
|
* console.log(response.data.message);
|
|
110
110
|
* ```
|
|
111
111
|
*/
|
|
112
112
|
async delete(id) {
|
|
113
|
-
return await this.http.delete(`/customer/invoice-
|
|
113
|
+
return await this.http.delete(`/customer/invoice-settings/${id}`);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
exports.
|
|
116
|
+
exports.InvoiceSettingsService = InvoiceSettingsService;
|
package/dist/taxRate.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface TaxRateData {
|
|
|
8
8
|
type: string;
|
|
9
9
|
[key: string]: any;
|
|
10
10
|
}
|
|
11
|
+
export type TaxRateType = 'SALES' | 'PURCHASES';
|
|
11
12
|
export interface TaxRate extends TaxRateData {
|
|
12
13
|
_id: string;
|
|
13
14
|
createdAt?: string;
|
|
@@ -16,16 +17,37 @@ export interface TaxRate extends TaxRateData {
|
|
|
16
17
|
export interface TaxRateQueryParams {
|
|
17
18
|
page?: number;
|
|
18
19
|
limit?: number;
|
|
20
|
+
type?: TaxRateType;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Service for Tax Rate
|
|
22
24
|
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* The `type` parameter is mandatory and determines the tax context:
|
|
27
|
+
*
|
|
28
|
+
* - `SALES` → Use this when creating or displaying **customer invoices**
|
|
29
|
+
* - `PURCHASES` → Use this when creating or displaying **vendor payments / expenses**
|
|
30
|
+
*
|
|
23
31
|
* @example
|
|
24
32
|
* ```ts
|
|
25
33
|
* const { createClient } = require('timber-sdk-dev');
|
|
26
34
|
* const client = createClient('your-api-key');
|
|
27
|
-
*
|
|
28
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* // Fetch tax rates for invoices
|
|
37
|
+
* const salesTaxes = await client.taxRate.list({
|
|
38
|
+
* page: 1,
|
|
39
|
+
* limit: 10,
|
|
40
|
+
* type: 'SALES'
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Fetch tax rates for vendor payments
|
|
44
|
+
* const purchaseTaxes = await client.taxRate.list({
|
|
45
|
+
* page: 1,
|
|
46
|
+
* limit: 10,
|
|
47
|
+
* type: 'PURCHASES'
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* console.log(salesTaxes.data);
|
|
29
51
|
* ```
|
|
30
52
|
*/
|
|
31
53
|
export declare class TaxRateService {
|
package/dist/taxRate.js
CHANGED
|
@@ -4,12 +4,32 @@ exports.TaxRateService = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* Service for Tax Rate
|
|
6
6
|
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* The `type` parameter is mandatory and determines the tax context:
|
|
9
|
+
*
|
|
10
|
+
* - `SALES` → Use this when creating or displaying **customer invoices**
|
|
11
|
+
* - `PURCHASES` → Use this when creating or displaying **vendor payments / expenses**
|
|
12
|
+
*
|
|
7
13
|
* @example
|
|
8
14
|
* ```ts
|
|
9
15
|
* const { createClient } = require('timber-sdk-dev');
|
|
10
16
|
* const client = createClient('your-api-key');
|
|
11
|
-
*
|
|
12
|
-
*
|
|
17
|
+
*
|
|
18
|
+
* // Fetch tax rates for invoices
|
|
19
|
+
* const salesTaxes = await client.taxRate.list({
|
|
20
|
+
* page: 1,
|
|
21
|
+
* limit: 10,
|
|
22
|
+
* type: 'SALES'
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Fetch tax rates for vendor payments
|
|
26
|
+
* const purchaseTaxes = await client.taxRate.list({
|
|
27
|
+
* page: 1,
|
|
28
|
+
* limit: 10,
|
|
29
|
+
* type: 'PURCHASES'
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* console.log(salesTaxes.data);
|
|
13
33
|
* ```
|
|
14
34
|
*/
|
|
15
35
|
class TaxRateService {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a nested object to FormData
|
|
3
|
+
* @param obj - The object to convert
|
|
4
|
+
* @param formData - The FormData instance (optional, creates new if not provided)
|
|
5
|
+
* @param parentKey - The parent key for nested properties (used internally)
|
|
6
|
+
* @returns FormData instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function convertToFormData(obj: any, formData?: FormData, parentKey?: string): FormData;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertToFormData = convertToFormData;
|
|
4
|
+
/**
|
|
5
|
+
* Converts a nested object to FormData
|
|
6
|
+
* @param obj - The object to convert
|
|
7
|
+
* @param formData - The FormData instance (optional, creates new if not provided)
|
|
8
|
+
* @param parentKey - The parent key for nested properties (used internally)
|
|
9
|
+
* @returns FormData instance
|
|
10
|
+
*/
|
|
11
|
+
function convertToFormData(obj, formData = new FormData(), parentKey = '') {
|
|
12
|
+
if (obj === null || obj === undefined) {
|
|
13
|
+
return formData;
|
|
14
|
+
}
|
|
15
|
+
Object.keys(obj).forEach(key => {
|
|
16
|
+
const value = obj[key];
|
|
17
|
+
const formKey = parentKey ? `${parentKey}[${key}]` : key;
|
|
18
|
+
// Handle null or undefined values - skip them
|
|
19
|
+
if (value === null || value === undefined) {
|
|
20
|
+
formData.append(formKey, '');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Handle File objects
|
|
24
|
+
if (value instanceof File) {
|
|
25
|
+
formData.append(formKey, value);
|
|
26
|
+
}
|
|
27
|
+
// Handle Blob objects
|
|
28
|
+
else if (value instanceof Blob) {
|
|
29
|
+
formData.append(formKey, value);
|
|
30
|
+
}
|
|
31
|
+
// Handle Date objects
|
|
32
|
+
else if (value instanceof Date) {
|
|
33
|
+
formData.append(formKey, value.toISOString());
|
|
34
|
+
}
|
|
35
|
+
// Handle Arrays
|
|
36
|
+
else if (Array.isArray(value)) {
|
|
37
|
+
// Handle empty arrays - mark them so backend can reconstruct
|
|
38
|
+
if (value.length === 0) {
|
|
39
|
+
formData.append(formKey, '[]');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
value.forEach((item, index) => {
|
|
43
|
+
const arrayKey = `${formKey}[${index}]`;
|
|
44
|
+
// If array item is an object, recurse
|
|
45
|
+
if (typeof item === 'object' &&
|
|
46
|
+
item !== null &&
|
|
47
|
+
!(item instanceof File) &&
|
|
48
|
+
!(item instanceof Blob)) {
|
|
49
|
+
convertToFormData(item, formData, arrayKey);
|
|
50
|
+
}
|
|
51
|
+
// If array item is a primitive or File/Blob, append with indexed key
|
|
52
|
+
else if (item !== null && item !== undefined) {
|
|
53
|
+
formData.append(arrayKey, item);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Handle nested objects (but not File/Blob/Date)
|
|
58
|
+
else if (typeof value === 'object' &&
|
|
59
|
+
!(value instanceof File) &&
|
|
60
|
+
!(value instanceof Blob) &&
|
|
61
|
+
!(value instanceof Date)) {
|
|
62
|
+
convertToFormData(value, formData, formKey);
|
|
63
|
+
}
|
|
64
|
+
// Handle primitives (string, number, boolean)
|
|
65
|
+
else {
|
|
66
|
+
// Convert booleans and numbers to strings
|
|
67
|
+
formData.append(formKey, String(value));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return formData;
|
|
71
|
+
}
|
package/package.json
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "timber-node",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Simplifying accounting and tax filing for businesses",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"timber"
|
|
7
|
-
],
|
|
8
|
-
"homepage": "https://github.com/TImber-UAE/timber-be-sdk-s#readme",
|
|
9
|
-
"bugs": {
|
|
10
|
-
"url": "https://github.com/TImber-UAE/timber-be-sdk-s/issues"
|
|
11
|
-
},
|
|
12
|
-
"repository": {
|
|
13
|
-
"type": "git",
|
|
14
|
-
"url": "git+https://github.com/TImber-UAE/timber-be-sdk-s.git"
|
|
15
|
-
},
|
|
16
|
-
"license": "MIT",
|
|
17
|
-
"author": "timberaccounting",
|
|
18
|
-
"main": "dist/index.js",
|
|
19
|
-
"types": "dist/index.d.ts",
|
|
20
|
-
"exports": {
|
|
21
|
-
".": {
|
|
22
|
-
"require": "./dist/index.js",
|
|
23
|
-
"default": "./dist/index.js"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"scripts": {
|
|
27
|
-
"dev": "nodemon src/index.js",
|
|
28
|
-
"build": "tsc",
|
|
29
|
-
"docs": "typedoc",
|
|
30
|
-
"prepare": "husky",
|
|
31
|
-
"lint": "eslint . --ext .ts,.js",
|
|
32
|
-
"lint:fix": "eslint . --ext .ts,.js --fix"
|
|
33
|
-
},
|
|
34
|
-
"lint-staged": {
|
|
35
|
-
"*.{js,ts,json,md}": [
|
|
36
|
-
"prettier --write",
|
|
37
|
-
"eslint --fix"
|
|
38
|
-
]
|
|
39
|
-
},
|
|
40
|
-
"dependencies": {
|
|
41
|
-
"axios": "^1.10.0",
|
|
42
|
-
"form-data": "^4.0.3",
|
|
43
|
-
"timber-node": "^0.0.5",
|
|
44
|
-
"typescript-eslint": "^8.35.0"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"@commitlint/cli": "^19.8.1",
|
|
48
|
-
"@commitlint/config-conventional": "^19.8.1",
|
|
49
|
-
"@types/node": "^24.0.4",
|
|
50
|
-
"@typescript-eslint/eslint-plugin": "^8.35.0",
|
|
51
|
-
"@typescript-eslint/parser": "^8.35.0",
|
|
52
|
-
"eslint": "^9.29.0",
|
|
53
|
-
"eslint-config-prettier": "^10.1.5",
|
|
54
|
-
"eslint-plugin-prettier": "^5.5.1",
|
|
55
|
-
"globals": "^16.2.0",
|
|
56
|
-
"husky": "^8.0.3",
|
|
57
|
-
"nodemon": "^3.1.10",
|
|
58
|
-
"prettier": "^3.6.2",
|
|
59
|
-
"typedoc": "^0.28.5",
|
|
60
|
-
"typedoc-plugin-markdown": "^4.7.0",
|
|
61
|
-
"typescript": "^5.8.3"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "timber-node",
|
|
3
|
+
"version": "0.4.5",
|
|
4
|
+
"description": "Simplifying accounting and tax filing for businesses",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"timber"
|
|
7
|
+
],
|
|
8
|
+
"homepage": "https://github.com/TImber-UAE/timber-be-sdk-s#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/TImber-UAE/timber-be-sdk-s/issues"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/TImber-UAE/timber-be-sdk-s.git"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "timberaccounting",
|
|
18
|
+
"main": "dist/index.js",
|
|
19
|
+
"types": "dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"require": "./dist/index.js",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"dev": "nodemon src/index.js",
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"docs": "typedoc",
|
|
30
|
+
"prepare": "husky",
|
|
31
|
+
"lint": "eslint . --ext .ts,.js",
|
|
32
|
+
"lint:fix": "eslint . --ext .ts,.js --fix"
|
|
33
|
+
},
|
|
34
|
+
"lint-staged": {
|
|
35
|
+
"*.{js,ts,json,md}": [
|
|
36
|
+
"prettier --write",
|
|
37
|
+
"eslint --fix"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"axios": "^1.10.0",
|
|
42
|
+
"form-data": "^4.0.3",
|
|
43
|
+
"timber-node": "^0.0.5",
|
|
44
|
+
"typescript-eslint": "^8.35.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@commitlint/cli": "^19.8.1",
|
|
48
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
49
|
+
"@types/node": "^24.0.4",
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^8.35.0",
|
|
51
|
+
"@typescript-eslint/parser": "^8.35.0",
|
|
52
|
+
"eslint": "^9.29.0",
|
|
53
|
+
"eslint-config-prettier": "^10.1.5",
|
|
54
|
+
"eslint-plugin-prettier": "^5.5.1",
|
|
55
|
+
"globals": "^16.2.0",
|
|
56
|
+
"husky": "^8.0.3",
|
|
57
|
+
"nodemon": "^3.1.10",
|
|
58
|
+
"prettier": "^3.6.2",
|
|
59
|
+
"typedoc": "^0.28.5",
|
|
60
|
+
"typedoc-plugin-markdown": "^4.7.0",
|
|
61
|
+
"typescript": "^5.8.3"
|
|
62
|
+
}
|
|
63
|
+
}
|