aves-sdk 1.2.2 → 1.2.4
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 +167 -321
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.d.cts +22 -0
- package/dist/tsconfig.build.d.ts +22 -0
- package/package.json +7 -35
- package/dist/index.d.cts +0 -2255
- package/dist/index.d.ts +0 -2255
package/README.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AVES SDK
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for
|
|
3
|
+
A type-safe TypeScript SDK for the AVES XML REST API. Automatically handles XML parsing, validation, case transformation, and provides full TypeScript support.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **Production Ready** - Tested, validated, optimized bundle
|
|
7
|
+
- **Type-safe** - Full TypeScript support with inferred types
|
|
8
|
+
- **Runtime validation** - Input/output validation using Valibot
|
|
9
|
+
- **XML handling** - Automatic XML ↔ JSON conversion
|
|
10
|
+
- **Case transformation** - Automatic camelCase ↔ PascalCase conversion
|
|
11
|
+
- **Error handling** - Custom error types with detailed error information
|
|
13
12
|
|
|
14
13
|
## Installation
|
|
15
14
|
|
|
@@ -25,384 +24,231 @@ bun add aves-sdk
|
|
|
25
24
|
|
|
26
25
|
## Quick Start
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
```typescript
|
|
28
|
+
import { AvesClient } from 'aves-sdk';
|
|
29
|
+
|
|
30
|
+
const client = new AvesClient(
|
|
31
|
+
'https://api.example.com', // Base URL
|
|
32
|
+
'025706', // 6-digit HostID
|
|
33
|
+
'TOKEN002756', // Xtoken
|
|
34
|
+
'02' // Optional: 2-digit language code (01=Italian, 02=English)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Search for records (camelCase input)
|
|
38
|
+
const results = await client.search({
|
|
39
|
+
searchType: 'CODE',
|
|
40
|
+
recordCode: '508558',
|
|
41
|
+
});
|
|
29
42
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
// Insert or update a record (camelCase input)
|
|
44
|
+
const response = await client.upsertRecord({
|
|
45
|
+
name: 'John Doe',
|
|
46
|
+
email: 'john@example.com',
|
|
47
|
+
address: '123 Main St',
|
|
48
|
+
zipCode: '12345',
|
|
49
|
+
cityName: 'New York',
|
|
50
|
+
stateCode: 'USA',
|
|
51
|
+
// ... other fields
|
|
52
|
+
});
|
|
35
53
|
```
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
## API Reference
|
|
38
56
|
|
|
39
|
-
|
|
40
|
-
import { Module } from '@nestjs/common';
|
|
41
|
-
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
42
|
-
import { AvesModule } from 'aves-sdk';
|
|
43
|
-
|
|
44
|
-
@Module({
|
|
45
|
-
imports: [
|
|
46
|
-
ConfigModule.forRoot({ isGlobal: true }),
|
|
47
|
-
AvesModule.forRootAsync({
|
|
48
|
-
imports: [ConfigModule],
|
|
49
|
-
useFactory: (config: ConfigService) => ({
|
|
50
|
-
baseUrl: config.get('AVES_BASE_URL')!,
|
|
51
|
-
hostId: config.get('AVES_HOST_ID')!,
|
|
52
|
-
xtoken: config.get('AVES_XTOKEN')!,
|
|
53
|
-
languageCode: config.get('AVES_LANGUAGE_CODE'),
|
|
54
|
-
}),
|
|
55
|
-
inject: [ConfigService],
|
|
56
|
-
}),
|
|
57
|
-
],
|
|
58
|
-
})
|
|
59
|
-
export class AppModule {}
|
|
60
|
-
```
|
|
57
|
+
### `AvesClient`
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
#### Constructor
|
|
63
60
|
|
|
64
61
|
```typescript
|
|
65
|
-
|
|
66
|
-
import { AvesService, SearchCustomerRequest } from 'aves-sdk';
|
|
67
|
-
|
|
68
|
-
@Injectable()
|
|
69
|
-
export class BookingService {
|
|
70
|
-
constructor(private readonly aves: AvesService) {}
|
|
71
|
-
|
|
72
|
-
async findCustomer(code: string) {
|
|
73
|
-
// Type-safe discriminated union
|
|
74
|
-
const request: SearchCustomerRequest = {
|
|
75
|
-
type: 'code',
|
|
76
|
-
code: code,
|
|
77
|
-
pagination: { pages: 50, page: 1 },
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const result = await this.aves.searchCustomers(request);
|
|
81
|
-
return result.customers; // Fully typed Customer[]
|
|
82
|
-
}
|
|
83
|
-
}
|
|
62
|
+
new AvesClient(baseURL: string, hostID: string, xtoken: string, languageCode?: string)
|
|
84
63
|
```
|
|
85
64
|
|
|
86
|
-
|
|
65
|
+
- `baseURL` - Base URL of the AVES API
|
|
66
|
+
- `hostID` - 6-digit identification code
|
|
67
|
+
- `xtoken` - Unique validation string
|
|
68
|
+
- `languageCode` - Optional: 2-digit language code (01=Italian, 02=English, etc.)
|
|
87
69
|
|
|
88
|
-
|
|
70
|
+
#### Methods
|
|
89
71
|
|
|
90
|
-
|
|
91
|
-
// Search by customer code - TypeScript knows only 'code' is available
|
|
92
|
-
const searchByCode: SearchCustomerRequest = {
|
|
93
|
-
type: 'code',
|
|
94
|
-
code: '123456',
|
|
95
|
-
// Only 'code' property available - type-safe!
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// Search by name - different fields available
|
|
99
|
-
const searchByName: SearchCustomerRequest = {
|
|
100
|
-
type: 'name',
|
|
101
|
-
name: 'Smith',
|
|
102
|
-
city: 'New York', // Optional for 'name' type
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// Search by VAT code
|
|
106
|
-
const searchByVat: SearchCustomerRequest = {
|
|
107
|
-
type: 'vat_code',
|
|
108
|
-
vatCode: 'IT12345678',
|
|
109
|
-
phoneNumber: '+39123456', // Optional for 'vat_code' type
|
|
110
|
-
};
|
|
72
|
+
##### `search(params)`
|
|
111
73
|
|
|
112
|
-
|
|
113
|
-
const searchByDate: SearchCustomerRequest = {
|
|
114
|
-
type: 'last_mod_date',
|
|
115
|
-
from: '2025-01-01',
|
|
116
|
-
to: '2025-12-31',
|
|
117
|
-
// 'from' and 'to' are required for this type
|
|
118
|
-
};
|
|
119
|
-
```
|
|
74
|
+
Search for master records by various criteria. The required fields depend on the `searchType` - TypeScript will enforce the correct fields for each search type.
|
|
120
75
|
|
|
121
|
-
|
|
76
|
+
**Search Types and Required Fields:**
|
|
122
77
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
| `search_field` | `searchField` | `pagination` |
|
|
133
|
-
| `external_ref_code` | `externalRefCode` | `pagination` |
|
|
78
|
+
- **`'CODE'`** - Requires `recordCode` (6 digits)
|
|
79
|
+
- **`'NAME'`** - Requires `name`, optionally `city`
|
|
80
|
+
- **`'VATCODE'`** - Requires `vatCode`, optionally `phoneNumber`
|
|
81
|
+
- **`'ZONE'`** - Requires `zipCode` and `countyCode`, optionally `city`
|
|
82
|
+
- **`'CATEGORY'`** - Requires `categoryCode`
|
|
83
|
+
- **`'EMAIL'`** - Requires `email`
|
|
84
|
+
- **`'LASTMODDATE'`** - Requires `lastModificationDate` with `minDate` and `maxDate`
|
|
85
|
+
- **`'SEARCH_FIELD'`** - Requires `searchFieldValue`
|
|
86
|
+
- **`'EXTERNAL_REF_CODE'`** - Requires `searchFieldValue`
|
|
134
87
|
|
|
135
|
-
|
|
88
|
+
All search types accept an optional `languageCode` (2-digit code).
|
|
136
89
|
|
|
137
|
-
|
|
90
|
+
**Examples:**
|
|
138
91
|
|
|
139
92
|
```typescript
|
|
140
|
-
// Search
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
pagination: { pages: 25, page: 1 },
|
|
93
|
+
// Search by code
|
|
94
|
+
const byCode = await client.search({
|
|
95
|
+
searchType: 'CODE',
|
|
96
|
+
recordCode: '508558',
|
|
145
97
|
});
|
|
146
98
|
|
|
147
|
-
//
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
status: 'enabled',
|
|
152
|
-
personalInfo: {
|
|
153
|
-
firstName: 'Mario',
|
|
154
|
-
lastName: 'Rossi',
|
|
155
|
-
dateOfBirth: '1990-01-01',
|
|
156
|
-
gender: 'male',
|
|
157
|
-
},
|
|
158
|
-
contact: {
|
|
159
|
-
email: { address: 'mario.rossi@example.com' },
|
|
160
|
-
phone: { number: '+39123456789' },
|
|
161
|
-
},
|
|
99
|
+
// Search by email
|
|
100
|
+
const byEmail = await client.search({
|
|
101
|
+
searchType: 'EMAIL',
|
|
102
|
+
email: 'user@example.com',
|
|
162
103
|
});
|
|
163
104
|
|
|
164
|
-
//
|
|
165
|
-
await
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Booking Management
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
// Create booking
|
|
175
|
-
const booking = await aves.createBooking({
|
|
176
|
-
customerId: '123456',
|
|
177
|
-
description: 'Summer vacation package',
|
|
178
|
-
startDate: '2025-07-01',
|
|
179
|
-
endDate: '2025-07-14',
|
|
180
|
-
currency: 'EUR',
|
|
181
|
-
passengers: [
|
|
182
|
-
{
|
|
183
|
-
id: '001',
|
|
184
|
-
type: 'adult',
|
|
185
|
-
firstName: 'Mario',
|
|
186
|
-
lastName: 'Rossi',
|
|
187
|
-
dateOfBirth: '1990-01-01',
|
|
188
|
-
gender: 'male',
|
|
189
|
-
},
|
|
190
|
-
],
|
|
191
|
-
services: [
|
|
192
|
-
{
|
|
193
|
-
id: 'HTL001',
|
|
194
|
-
type: 'hotel',
|
|
195
|
-
status: 'pending',
|
|
196
|
-
name: 'Hotel Paradise',
|
|
197
|
-
startDate: '2025-07-01',
|
|
198
|
-
endDate: '2025-07-14',
|
|
199
|
-
},
|
|
200
|
-
],
|
|
201
|
-
statisticCodes: {
|
|
202
|
-
code2: 'USA',
|
|
203
|
-
code3: 'GEN',
|
|
204
|
-
},
|
|
205
|
-
printDocument: false,
|
|
206
|
-
sendDocumentViaEmail: false,
|
|
105
|
+
// Search by name (with optional city)
|
|
106
|
+
const byName = await client.search({
|
|
107
|
+
searchType: 'NAME',
|
|
108
|
+
name: 'John Doe',
|
|
109
|
+
city: 'New York', // Optional
|
|
207
110
|
});
|
|
208
111
|
|
|
209
|
-
//
|
|
210
|
-
await
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
112
|
+
// Search by zone (requires zipCode and countyCode)
|
|
113
|
+
const byZone = await client.search({
|
|
114
|
+
searchType: 'ZONE',
|
|
115
|
+
zipCode: '47841',
|
|
116
|
+
countyCode: 'RN',
|
|
117
|
+
city: 'Cattolica', // Optional
|
|
215
118
|
});
|
|
216
119
|
|
|
217
|
-
//
|
|
218
|
-
await
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
120
|
+
// Search by last modification date
|
|
121
|
+
const byDate = await client.search({
|
|
122
|
+
searchType: 'LASTMODDATE',
|
|
123
|
+
lastModificationDate: {
|
|
124
|
+
minDate: '2024-01-01',
|
|
125
|
+
maxDate: '2024-12-31',
|
|
126
|
+
},
|
|
224
127
|
});
|
|
225
128
|
```
|
|
226
129
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
// Print booking documents
|
|
231
|
-
const result = await aves.printDocument({
|
|
232
|
-
bookingId: 'BK/2025/001',
|
|
233
|
-
customerId: '123456',
|
|
234
|
-
documentType: 'voucher',
|
|
235
|
-
format: 'pdf',
|
|
236
|
-
language: '01',
|
|
237
|
-
});
|
|
130
|
+
##### `upsertRecord(record)`
|
|
238
131
|
|
|
239
|
-
|
|
240
|
-
result.data.documents.forEach((doc) => {
|
|
241
|
-
console.log(doc.fileName);
|
|
242
|
-
console.log(doc.content); // Base64 content
|
|
243
|
-
console.log(doc.contentSize);
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### Payment Management
|
|
132
|
+
Insert or update a master record. The `insertCriteria` defaults to `'T'` (update all fields if exists) but can be overridden by including it in the record.
|
|
248
133
|
|
|
249
134
|
```typescript
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
135
|
+
const response = await client.upsertRecord({
|
|
136
|
+
name: string,
|
|
137
|
+
email: string,
|
|
138
|
+
address: string,
|
|
139
|
+
zipCode: string,
|
|
140
|
+
cityName: string,
|
|
141
|
+
countyCode: string,
|
|
142
|
+
stateCode: string,
|
|
143
|
+
firstPhoneNumber: string,
|
|
144
|
+
mobilePhoneNumber: string,
|
|
145
|
+
fiscalCode: string,
|
|
146
|
+
birthDate: string,
|
|
147
|
+
gender: string,
|
|
148
|
+
languageCode: string,
|
|
149
|
+
categoryCode: string,
|
|
150
|
+
recordCode: string, // Optional: 6-digit code
|
|
151
|
+
insertCriteria: 'S' | 'N' | 'T' | 'M', // Optional: defaults to 'T'
|
|
152
|
+
// ... see types for full list
|
|
266
153
|
});
|
|
267
154
|
```
|
|
268
155
|
|
|
269
|
-
|
|
156
|
+
**Insert Criteria:**
|
|
270
157
|
|
|
271
|
-
|
|
158
|
+
- `'S'` - Insert always new record
|
|
159
|
+
- `'N'` - If record exists, do not update
|
|
160
|
+
- `'T'` - If record exists, update all fields (default)
|
|
161
|
+
- `'M'` - If record exists, update only secondary fields
|
|
272
162
|
|
|
273
|
-
|
|
274
|
-
type CustomerType = 'customer' | 'supplier' | 'voucher' | 'supplier_voucher';
|
|
275
|
-
type CustomerStatusType = 'enabled' | 'warning' | 'blacklisted' | 'disabled';
|
|
276
|
-
type PassengerType = 'adult' | 'child' | 'infant' | 'senior';
|
|
277
|
-
type GenderType = 'male' | 'female';
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Booking Types
|
|
163
|
+
**Example:**
|
|
281
164
|
|
|
282
165
|
```typescript
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
166
|
+
// Default behavior (update all fields if exists)
|
|
167
|
+
const response = await client.upsertRecord({
|
|
168
|
+
name: 'Jane Smith',
|
|
169
|
+
email: 'jane@example.com',
|
|
170
|
+
address: '456 Oak Ave',
|
|
171
|
+
zipCode: '67890',
|
|
172
|
+
cityName: 'Los Angeles',
|
|
173
|
+
stateCode: 'USA',
|
|
174
|
+
firstPhoneNumber: '+1234567890',
|
|
175
|
+
languageCode: '02',
|
|
176
|
+
});
|
|
291
177
|
|
|
292
|
-
|
|
178
|
+
// Override insertCriteria
|
|
179
|
+
const newRecord = await client.upsertRecord({
|
|
180
|
+
name: 'John Doe',
|
|
181
|
+
insertCriteria: 'S', // Always insert new
|
|
182
|
+
email: 'john@example.com',
|
|
183
|
+
// ... other fields
|
|
184
|
+
});
|
|
293
185
|
|
|
294
|
-
|
|
295
|
-
type DocumentType =
|
|
296
|
-
| 'visa_request'
|
|
297
|
-
| 'travel_information'
|
|
298
|
-
| 'voucher'
|
|
299
|
-
| 'booking_contract'
|
|
300
|
-
| 'booking_confirmation'
|
|
301
|
-
| 'supplier_service_list'
|
|
302
|
-
| 'invoice'
|
|
303
|
-
| 'proforma_invoice'
|
|
304
|
-
| 'adeguamento'
|
|
305
|
-
| 'reservation_form'
|
|
306
|
-
| 'open_xml'
|
|
307
|
-
| 'sales_invoice'
|
|
308
|
-
| 'ticketing_tmaster'
|
|
309
|
-
| 'summary_form';
|
|
186
|
+
console.log(response.customerRecordRS?.customerRecordCode);
|
|
310
187
|
```
|
|
311
188
|
|
|
312
|
-
##
|
|
313
|
-
|
|
314
|
-
### Search Response with Pagination
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
interface CustomerSearchResult {
|
|
318
|
-
customers: Customer[];
|
|
319
|
-
pagination: {
|
|
320
|
-
page: number; // Current page
|
|
321
|
-
pages: number; // Minimum known pages
|
|
322
|
-
totalItems: number; // Items in this response
|
|
323
|
-
hasMore: boolean; // More results available
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
```
|
|
189
|
+
## Error Handling
|
|
327
190
|
|
|
328
|
-
|
|
191
|
+
The SDK throws `AvesError` for API errors and validation failures:
|
|
329
192
|
|
|
330
193
|
```typescript
|
|
331
|
-
|
|
332
|
-
emailRecipient?: string;
|
|
333
|
-
documents: PrintedDocument[];
|
|
334
|
-
additionalDocuments?: {
|
|
335
|
-
emailRecipient: string;
|
|
336
|
-
documents: PrintedDocument[];
|
|
337
|
-
}[];
|
|
338
|
-
}
|
|
194
|
+
import { AvesError } from 'aves-sdk';
|
|
339
195
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
196
|
+
try {
|
|
197
|
+
await client.search({ searchType: 'CODE', recordCode: '123' });
|
|
198
|
+
} catch (error) {
|
|
199
|
+
if (error instanceof AvesError) {
|
|
200
|
+
console.error('Status:', error.status); // 'ERROR' | 'TIMEOUT' | 'WARNING'
|
|
201
|
+
console.error('Error Code:', error.errorCode);
|
|
202
|
+
console.error('Description:', error.errorDescription);
|
|
203
|
+
}
|
|
344
204
|
}
|
|
345
205
|
```
|
|
346
206
|
|
|
347
|
-
##
|
|
207
|
+
## Case Transformation
|
|
348
208
|
|
|
349
|
-
|
|
209
|
+
The SDK automatically handles case transformation between your code and the API:
|
|
350
210
|
|
|
351
|
-
|
|
352
|
-
|
|
211
|
+
- **Input**: Use camelCase (e.g., `recordCode`, `zipCode`)
|
|
212
|
+
- **API**: Automatically converted to PascalCase with XML attributes (e.g., `@RecordCode`, `ZipCode`)
|
|
213
|
+
- **Output**: Automatically converted back to camelCase
|
|
353
214
|
|
|
354
|
-
|
|
355
|
-
if (!result.success) {
|
|
356
|
-
console.error(result.error.issues);
|
|
357
|
-
}
|
|
358
|
-
```
|
|
215
|
+
You never need to worry about case conversion or XML attribute prefixes - the SDK handles it all.
|
|
359
216
|
|
|
360
|
-
##
|
|
217
|
+
## Type Safety
|
|
361
218
|
|
|
362
|
-
|
|
363
|
-
import { AvesErrorHandler, AvesErrorCodes } from 'aves-sdk';
|
|
219
|
+
All types are exported and inferred from the validation schemas:
|
|
364
220
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
221
|
+
```typescript
|
|
222
|
+
import type {
|
|
223
|
+
SearchMasterRecordRS,
|
|
224
|
+
ManageMasterRecordRS,
|
|
225
|
+
MasterRecordDetail,
|
|
226
|
+
} from 'aves-sdk';
|
|
227
|
+
|
|
228
|
+
// Use types for your functions
|
|
229
|
+
function processRecord(record: MasterRecordDetail) {
|
|
230
|
+
// TypeScript knows all available fields in camelCase
|
|
370
231
|
}
|
|
371
232
|
```
|
|
372
233
|
|
|
373
|
-
##
|
|
374
|
-
|
|
375
|
-
Optimized for production:
|
|
234
|
+
## Validation
|
|
376
235
|
|
|
377
|
-
|
|
378
|
-
- **CJS**: 55.13 KB (gzipped)
|
|
379
|
-
- **DTS**: 137.03 KB
|
|
236
|
+
The SDK validates all inputs and outputs using Valibot schemas:
|
|
380
237
|
|
|
381
|
-
|
|
238
|
+
- **HostID**: Must be exactly 6 digits
|
|
239
|
+
- **RecordCode**: Must be exactly 6 characters
|
|
240
|
+
- **LanguageCode**: Must be exactly 2 digits (01=Italian, 02=English, etc.)
|
|
241
|
+
- **Search parameters**: Required fields are enforced based on `searchType` using discriminated unions
|
|
242
|
+
- All other fields follow the AVES API specification
|
|
382
243
|
|
|
383
|
-
|
|
384
|
-
aves-sdk/
|
|
385
|
-
├── validation/
|
|
386
|
-
│ └── api-schemas.ts # Zod schemas + inferred types (single source of truth)
|
|
387
|
-
├── types/
|
|
388
|
-
│ ├── interfaces.ts # XML layer (Aves API)
|
|
389
|
-
│ └── common.ts # Shared types
|
|
390
|
-
├── mappers/
|
|
391
|
-
│ ├── request-mappers.ts # API → XML
|
|
392
|
-
│ ├── response-mappers.ts # XML → API
|
|
393
|
-
│ └── type-mappers.ts # Enum conversions
|
|
394
|
-
├── nest/
|
|
395
|
-
│ ├── aves.module.ts # NestJS module
|
|
396
|
-
│ └── aves.service.ts # Main service
|
|
397
|
-
└── config/
|
|
398
|
-
├── endpoints.ts # API endpoints
|
|
399
|
-
└── root-elements.ts # XML root elements
|
|
400
|
-
```
|
|
244
|
+
Invalid data will throw a validation error before making the API request. All validation happens on camelCase input, making it easy to use. TypeScript will also provide type checking and autocomplete based on the selected `searchType`.
|
|
401
245
|
|
|
402
246
|
## License
|
|
403
247
|
|
|
404
248
|
MIT
|
|
405
249
|
|
|
406
|
-
##
|
|
250
|
+
## Links
|
|
407
251
|
|
|
408
|
-
|
|
252
|
+
- [GitHub Repository](https://github.com/simoneguglielmi/aves-sdk)
|
|
253
|
+
- [NPM Package](https://npmjs.com/package/aves-sdk)
|
|
254
|
+
- [Issue Tracker](https://github.com/simoneguglielmi/aves-sdk/issues)
|