aves-sdk 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,6 @@
1
1
  # AVES SDK
2
2
 
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
-
5
- ## Features
6
-
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
- - **Functional error handling** - Result pattern for type-safe error handling
3
+ Type-safe TypeScript SDK for the AVES XML REST API. Handles XML parsing, Valibot validation, camelCase ↔ PascalCase / `@` attrs, and returns `Result` instead of throwing.
12
4
 
13
5
  ## Installation
14
6
 
@@ -22,292 +14,459 @@ pnpm add aves-sdk
22
14
  bun add aves-sdk
23
15
  ```
24
16
 
25
- ## Quick Start
17
+ ## Quick start
26
18
 
27
19
  ```typescript
28
20
  import { AvesClient } from 'aves-sdk';
29
21
 
30
- const client = new AvesClient(
31
- 'https://api.example.com', // Base URL
32
- 'hostid', // 6-digit HostID
33
- 'TOKEN', // Xtoken
34
- '02' // Optional: 2-digit language code (01=Italian, 02=English)
35
- );
22
+ const client = new AvesClient({
23
+ baseURL: 'https://api.example.com',
24
+ hostID: '000000', // 6 digits
25
+ xtoken: 'TOKEN',
26
+ languageCode: '02', // optional: 01=Italian, 02=English
27
+ timeoutMs: 30_000, // optional
28
+ });
36
29
 
37
- // Search for records
38
- const searchResult = await client.search({
30
+ const result = await client.search({
39
31
  searchType: 'CODE',
40
32
  recordCode: '508558',
41
33
  });
42
34
 
43
- if (searchResult.success) {
44
- console.log(searchResult.data); // SearchMasterRecordRS
35
+ if (result.success) {
36
+ console.log(result.data.masterRecordList);
45
37
  } else {
46
- console.error(searchResult.error); // AvesError
38
+ console.error(result.error.kind, result.error.message, result.error.code);
47
39
  }
40
+ ```
48
41
 
49
- // Insert or update a record
50
- const upsertResult = await client.upsertRecord({
51
- name: 'John Doe',
52
- email: 'john@example.com',
53
- address: '123 Main St',
54
- zipCode: '12345',
55
- cityName: 'New York',
56
- stateCode: 'USA',
57
- languageCode: '02',
58
- // ... other fields
59
- });
42
+ ## Client shape
60
43
 
61
- if (upsertResult.success) {
62
- console.log(upsertResult.data.customerRecordRS?.customerRecordCode);
63
- } else {
64
- console.error(
65
- upsertResult.error.errorCode,
66
- upsertResult.error.errorDescription
67
- );
68
- }
69
- ```
44
+ `AvesClient` is a facade over domain clients. **Prefer namespaces.** Flat methods are auto-bound from domain prototypes (no hand-maintained forwarders).
70
45
 
71
- ## API Reference
46
+ ```typescript
47
+ // canonical
48
+ await client.booking.createBooking(params);
49
+ await client.packages.searchPackages(params);
50
+ await client.master.search({ searchType: 'CODE', recordCode: '508558' });
51
+
52
+ // flat compat (same implementations)
53
+ await client.createBooking(params);
54
+ await client.searchPackages(params);
55
+ await client.search({ searchType: 'CODE', recordCode: '508558' });
56
+ ```
72
57
 
73
- ### `AvesClient`
58
+ | Namespace | Methods |
59
+ | --------- | ------- |
60
+ | `master` | `search`, `upsertRecord` |
61
+ | `booking` | `createBooking`, `modBookingServices`, `modBookingHeader`, `cancelBooking`, `setBookingStatus`, `setBookingServiceStatus`, `insertFilePaymentList`, `searchBookingFiles` |
62
+ | `packages` | `searchPackages`, `searchTopServices`, `getPackageDetail`, `commitPackage` |
74
63
 
75
- #### Constructor
64
+ ### Constructor
76
65
 
77
66
  ```typescript
78
- new AvesClient(baseURL: string, hostID: string, xtoken: string, languageCode?: string)
67
+ new AvesClient(options: AvesClientOptions, deps?: AvesClientDeps)
79
68
  ```
80
69
 
81
- - `baseURL` - Base URL of the AVES API
82
- - `hostID` - 6-digit identification code
83
- - `xtoken` - Unique validation string
84
- - `languageCode` - Optional: 2-digit language code (01=Italian, 02=English, etc.)
70
+ | Option | Description |
71
+ | ------ | ----------- |
72
+ | `baseURL` | AVES API base URL |
73
+ | `hostID` | 6-digit host id |
74
+ | `xtoken` | Auth token |
75
+ | `languageCode` | Optional 2-digit language code |
76
+ | `timeoutMs` | Optional request timeout (default 30000) |
77
+
78
+ Optional DI (tests / custom transport):
79
+
80
+ ```typescript
81
+ import {
82
+ AvesClient,
83
+ AvesTransport,
84
+ BookingClient,
85
+ } from 'aves-sdk';
86
+
87
+ const transport = new AvesTransport(options);
88
+ new AvesClient(options, {
89
+ transport,
90
+ booking: new BookingClient(transport),
91
+ });
92
+ ```
85
93
 
86
- #### Methods
94
+ ### Result type
87
95
 
88
- ##### `search(params)`
96
+ All methods return `Result<T, AvesError>` — they do **not** throw.
89
97
 
90
- Search for master records by various criteria. The required fields depend on the `searchType` - TypeScript will enforce the correct fields for each search type.
98
+ ```typescript
99
+ type Result<T, E> =
100
+ | { success: true; data: T }
101
+ | { success: false; error: E };
102
+ ```
91
103
 
92
- **Search Types and Required Fields:**
104
+ ---
93
105
 
94
- - **`'CODE'`** - Requires `recordCode` (6 digits)
95
- - **`'NAME'`** - Requires `name`, optionally `city`
96
- - **`'VATCODE'`** - Requires `vatCode`, optionally `phoneNumber`
97
- - **`'ZONE'`** - Requires `zipCode` and `countyCode`, optionally `city`
98
- - **`'CATEGORY'`** - Requires `categoryCode`
99
- - **`'EMAIL'`** - Requires `email`
100
- - **`'LASTMODDATE'`** - Requires `lastModificationDate` with `minDate` and `maxDate`
101
- - **`'SEARCH_FIELD'`** - Requires `searchFieldValue`
102
- - **`'EXTERNAL_REF_CODE'`** - Requires `searchFieldValue`
106
+ ## Master records
103
107
 
104
- All search types accept an optional `languageCode` (2-digit code).
108
+ ### `search(params)` / `client.master.search`
105
109
 
106
- **Examples:**
110
+ | `searchType` | Required fields |
111
+ | ------------ | --------------- |
112
+ | `'CODE'` | `recordCode` |
113
+ | `'NAME'` | `name` (+ optional `city`) |
114
+ | `'VATCODE'` | `vatCode` (+ optional `phoneNumber`) |
115
+ | `'ZONE'` | `zipCode`, `countyCode` (+ optional `city`) |
116
+ | `'CATEGORY'` | `categoryCode` |
117
+ | `'EMAIL'` | `email` |
118
+ | `'LASTMODDATE'` | `lastModificationDate: { minDate, maxDate }` |
119
+ | `'SEARCH_FIELD'` / `'EXTERNAL_REF_CODE'` | `searchFieldValue` |
107
120
 
108
121
  ```typescript
109
- // Search by code
110
- const byCode = await client.search({
122
+ const byCode = await client.master.search({
111
123
  searchType: 'CODE',
112
124
  recordCode: '508558',
113
125
  });
114
126
 
115
- if (byCode.success) {
116
- console.log('Found records:', byCode.data.masterRecordList);
117
- }
118
-
119
- // Search by email
120
127
  const byEmail = await client.search({
121
128
  searchType: 'EMAIL',
122
129
  email: 'user@example.com',
123
130
  });
131
+ ```
124
132
 
125
- if (byEmail.success) {
126
- console.log('Found:', byEmail.data.masterRecordList);
127
- } else {
128
- console.error('Error:', byEmail.error.message);
129
- }
133
+ ### `upsertRecord(record)` / `client.master.upsertRecord`
130
134
 
131
- // Search by name (with optional city)
132
- const byName = await client.search({
133
- searchType: 'NAME',
134
- name: 'John Doe',
135
- city: 'New York', // Optional
135
+ `insertCriteria`: `'S'` always insert · `'N'` skip if exists · `'T'` update all (default) · `'M'` secondary fields only.
136
+
137
+ ```typescript
138
+ const result = await client.upsertRecord({
139
+ name: 'Jane Smith',
140
+ email: 'jane@example.com',
141
+ languageCode: '02',
142
+ insertCriteria: 'T',
136
143
  });
137
144
 
138
- // Search by zone (requires zipCode and countyCode)
139
- const byZone = await client.search({
140
- searchType: 'ZONE',
141
- zipCode: '47841',
142
- countyCode: 'RN',
143
- city: 'Cattolica', // Optional
145
+ if (result.success) {
146
+ console.log(result.data.masterRecordDetail?.recordCode);
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Booking
153
+
154
+ `*List` request fields are **flat arrays of Detail objects**. The SDK wraps them to AVES List/Detail XML.
155
+
156
+ | Method | Purpose |
157
+ | ------ | ------- |
158
+ | `createBooking` | Create booking file |
159
+ | `modBookingServices` | Add/replace services, assign package, delete/nullify lines |
160
+ | `modBookingHeader` | Header only (pax, notes, billing) — no costs |
161
+ | `cancelBooking` | Delete booking file |
162
+ | `setBookingStatus` | Change file status (`CANCELED` / `NULLIFIED` / …) |
163
+ | `setBookingServiceStatus` | Nullify a single service line |
164
+ | `insertFilePaymentList` | Register payments |
165
+ | `searchBookingFiles` | Search practices (`FILE_CODE`, `PAX_NAME`, `PACKAGE_CODE`, `OTHER`) |
166
+
167
+ ### Create
168
+
169
+ ```typescript
170
+ const created = await client.booking.createBooking({
171
+ customerDetail: { recordCode: '138311' },
172
+ bookingFileStatus: { value: 'QUOTATION' },
173
+ startDate: '2015-01-22T00:00:00',
174
+ endDate: '2015-01-25T00:00:00',
175
+ selectedServiceList: [
176
+ {
177
+ sCode: 'HT00110840',
178
+ ssCode: 'DL',
179
+ avesServiceType: 'TOP',
180
+ toServiceType: 'RESIDENCE',
181
+ startDate: '2015-01-22T00:00:00',
182
+ endDate: '2015-01-25T00:00:00',
183
+ qty: '1',
184
+ pax: '2',
185
+ paxAssociated: [],
186
+ avesSession: '1',
187
+ },
188
+ ],
189
+ passengerList: [
190
+ {
191
+ rph: '001',
192
+ roomRph: '001',
193
+ name: 'ADULTI 001',
194
+ categoryCode: 'AD', // required on create
195
+ sex: 'M',
196
+ },
197
+ ],
144
198
  });
145
199
 
146
- // Search by last modification date
147
- const byDate = await client.search({
148
- searchType: 'LASTMODDATE',
149
- lastModificationDate: {
150
- minDate: '2024-01-01',
151
- maxDate: '2024-12-31',
200
+ if (created.success) {
201
+ console.log(created.data.bookingFileDetail?.bookingFileCode);
202
+ }
203
+ ```
204
+
205
+ ### Modify services / package / overwrite lines
206
+
207
+ ```typescript
208
+ await client.booking.modBookingServices({
209
+ customerRecordCode: '138311',
210
+ bookingFileCode: '14/036654',
211
+ selectedPackageDetail: {
212
+ pCode: '2014MDE0000010',
213
+ startDate: '2015-01-22T00:00:00',
214
+ endDate: '2015-01-25T00:00:00',
152
215
  },
216
+ cancellableBookedServiceList: [
217
+ {
218
+ cancelOperationType: 'DELETE', // or 'NULLIFY'
219
+ serviceRefType: 'RPH',
220
+ serviceRefValue: '001',
221
+ },
222
+ ],
223
+ selectedServiceList: [
224
+ {
225
+ sCode: 'HT00110840',
226
+ avesServiceType: 'TOP',
227
+ toServiceType: 'RESIDENCE',
228
+ startDate: '2015-01-22T00:00:00',
229
+ endDate: '2015-01-25T00:00:00',
230
+ qty: '1',
231
+ pax: '2',
232
+ avesSession: '1',
233
+ bookedServiceRef: '001',
234
+ serviceFare: { currencyCode: 'EUR', cost: '100.00', price: '120.00' },
235
+ },
236
+ ],
153
237
  });
154
238
  ```
155
239
 
156
- ##### `upsertRecord(record)`
240
+ ### Payments
157
241
 
158
- 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.
242
+ Requires `bookingFileCode` **or** `bookingFileRefCode`.
243
+
244
+ `paymentUser` is serialized as an XML **attribute** on `FilePaymentListRQ` (`PaymentUser="…"`), not as a child element.
159
245
 
160
246
  ```typescript
161
- const result = await client.upsertRecord({
162
- name: string,
163
- email: string,
164
- address: string,
165
- zipCode: string,
166
- cityName: string,
167
- countyCode: string,
168
- stateCode: string,
169
- firstPhoneNumber: string,
170
- mobilePhoneNumber: string,
171
- fiscalCode: string,
172
- birthDate: string,
173
- gender: string,
174
- languageCode: string, // Required
175
- categoryCode: string,
176
- recordCode: string, // Optional: 6-digit code
177
- insertCriteria: 'S' | 'N' | 'T' | 'M', // Optional: defaults to 'T'
178
- // ... see types for full list
247
+ await client.booking.insertFilePaymentList({
248
+ bookingFileCode: '18/000172',
249
+ paymentUser: 'MLDN',
250
+ enableMultiplePayments: true,
251
+ operationType: 'AbsoluteAmountsInsertion',
252
+ filePaymentList: [
253
+ {
254
+ paymentDate: '2018-09-08',
255
+ paymentNote: 'INCASSO',
256
+ amount: '100.00',
257
+ paymentType: 'B', // C cash | B bank | R card | …
258
+ },
259
+ ],
179
260
  });
261
+ ```
180
262
 
181
- // Result is Result<ManageMasterRecordRS, AvesError>
182
- if (result.success) {
183
- // Access result.data
184
- } else {
185
- // Handle result.error
186
- }
263
+ ### Header, status, cancel, search practices
264
+
265
+ ```typescript
266
+ await client.booking.modBookingHeader({
267
+ bookingFileCode: '14/000043',
268
+ bookingFileStartDate: '2014-04-28',
269
+ customerRecordCode: '103737',
270
+ passengerList: [{ rph: '001', name: 'ADULTI 001', sex: 'M' }],
271
+ });
272
+
273
+ await client.booking.setBookingStatus({
274
+ customerRecordCode: '000170',
275
+ bookingFileCode: '14/000081',
276
+ fileStatus: { value: 'CANCELED' },
277
+ });
278
+
279
+ await client.booking.setBookingServiceStatus({
280
+ customerRecordCode: '000001',
281
+ bookingFileCode: '18/000252',
282
+ bookingServiceRef: '002',
283
+ bookingFileServiceStatus: 'NULLIFIED',
284
+ });
285
+
286
+ await client.booking.cancelBooking({
287
+ bookingFileCode: '14/000081',
288
+ customerRecordCode: '000170',
289
+ });
290
+
291
+ await client.booking.searchBookingFiles({
292
+ searchType: 'PACKAGE_CODE',
293
+ customerRecordCode: '138311',
294
+ packageCode: '2014MDE0000010',
295
+ });
187
296
  ```
188
297
 
189
- **Insert Criteria:**
298
+ ---
299
+
300
+ ## Package / Program catalog
190
301
 
191
- - `'S'` - Insert always new record
192
- - `'N'` - If record exists, do not update
193
- - `'T'` - If record exists, update all fields (default)
194
- - `'M'` - If record exists, update only secondary fields
302
+ There is **no** Create Package API in AVES XML 1.8.0. Search, detail, and commit (publish) are supported.
195
303
 
196
- **Example:**
304
+ | Method | Purpose |
305
+ | ------ | ------- |
306
+ | `searchPackages` | Search programs (`avesSearchType`: `PACKAGE` / `PROGRAM`) |
307
+ | `searchTopServices` | Search TOP services (`avesSearchType`: `SERVICE`) |
308
+ | `getPackageDetail` | Package base info + service list |
309
+ | `commitPackage` | Publish existing package (`packageCode` only) |
197
310
 
198
311
  ```typescript
199
- // Default behavior (update all fields if exists)
200
- const response = await client.upsertRecord({
201
- name: 'Jane Smith',
202
- email: 'jane@example.com',
203
- address: '456 Oak Ave',
204
- zipCode: '67890',
205
- cityName: 'Los Angeles',
206
- stateCode: 'USA',
207
- firstPhoneNumber: '+1234567890',
208
- languageCode: '02',
312
+ const packages = await client.packages.searchPackages({
313
+ baseSearch: {
314
+ customerRecordCode: '138311',
315
+ languageCode: '01',
316
+ currencyCode: 'EUR',
317
+ startDate: '2014-12-27T00:00:00',
318
+ endDate: '2015-01-03T00:00:00',
319
+ passengerList: [
320
+ {
321
+ rph: '001',
322
+ roomRph: '001',
323
+ name: 'ADULTI 001',
324
+ categoryCode: 'AD',
325
+ sex: 'M',
326
+ },
327
+ ],
328
+ },
329
+ avesSearchType: 'PACKAGE',
330
+ paxQty: '1',
331
+ paxQtyCriteria: 'GREATER_OR_EQUAL',
332
+ servOrPackCode: '2014MDE0000010',
209
333
  });
210
334
 
211
- if (response.success) {
212
- console.log(response.data.customerRecordRS?.customerRecordCode);
213
- } else {
214
- console.error('Failed:', response.error.message);
215
- }
216
-
217
- // Override insertCriteria
218
- const newRecord = await client.upsertRecord({
219
- name: 'John Doe',
220
- insertCriteria: 'S', // Always insert new
221
- email: 'john@example.com',
222
- languageCode: '02',
223
- // ... other fields
335
+ const detail = await client.packages.getPackageDetail({
336
+ customerRecordCode: '001692',
337
+ packageCode: '2015F042',
338
+ startDate: '2015-05-02T00:00:00',
339
+ endDate: '2015-05-05T00:00:00',
340
+ selectedServiceList: [
341
+ { serviceCode: 'PFRM04 PAR', packageRow: '01' },
342
+ ],
224
343
  });
225
344
 
226
- if (newRecord.success) {
227
- console.log('Created:', newRecord.data.customerRecordRS?.customerRecordCode);
228
- }
345
+ await client.packages.commitPackage({ packageCode: '14/PACKAGE001' });
229
346
  ```
230
347
 
231
- ## Error Handling
348
+ ---
232
349
 
233
- The SDK uses a functional `Result` pattern for type-safe error handling. All methods return `Result<Success, AvesError>` instead of throwing exceptions:
350
+ ## Errors
234
351
 
235
352
  ```typescript
236
- import { AvesClient, AvesError, type Result } from 'aves-sdk';
353
+ import { AvesClient, AvesError } from 'aves-sdk';
237
354
 
238
355
  const result = await client.search({
239
356
  searchType: 'CODE',
240
357
  recordCode: '508558',
241
358
  });
242
359
 
243
- if (result.success) {
244
- // TypeScript knows result.data is SearchMasterRecordRS
245
- console.log(result.data.masterRecordList);
246
- } else {
247
- // TypeScript knows result.error is AvesError
248
- console.error('Status:', result.error.status); // 'ERROR' | 'TIMEOUT' | 'WARNING'
249
- console.error('Error Code:', result.error.errorCode);
250
- console.error('Description:', result.error.errorDescription);
360
+ if (!result.success) {
361
+ // kind: 'validation' | 'api' | 'unknown'
362
+ console.error(result.error.kind, result.error.message, result.error.code);
251
363
  }
252
364
  ```
253
365
 
254
- **Result Type:**
366
+ ---
255
367
 
256
- ```typescript
257
- type Result<T, E> = { success: true; data: T } | { success: false; error: E };
258
- ```
368
+ ## Case transformation & wire shapes
369
+
370
+ - **Input**: camelCase (`recordCode`, `selectedServiceList`, `paymentUser`)
371
+ - **Wire**: PascalCase keys; `@`-prefixed keys become XML attributes
372
+ - **Output**: camelCase again
373
+
374
+ You do not handle XML attribute prefixes yourself. Attr vs element is decided by a **per-request `WireShape`** (`src/utils/wire-shapes.ts`), not a global field set.
375
+
376
+ ### Pipeline
377
+
378
+ One outbound path for all ops:
379
+
380
+ 1. Valibot validates camelCase input
381
+ 2. `createApiSchema(schema, shape, wrap?)` → `toWireBody` (optional list wrap + empty `paxAssociated` normalize + `camelToPascalKeys`)
382
+ 3. `AvesTransport.invokeOp` adds `RqHeader`, optional `bodyKey` nest, POSTs XML
259
383
 
260
- This pattern ensures:
384
+ Element-only roots use `elementOnlyWire` (`{}`). Master upsert nests under `bodyKey: "MasterRecordDetail"`; master search and booking spread fields at the RQ root.
261
385
 
262
- - **Type safety**: TypeScript narrows the type based on `success`
263
- - **No exceptions**: All errors are explicit in the return type
264
- - **Functional style**: Easier to compose and chain operations
386
+ ### Request shapes (one family per op)
265
387
 
266
- ## Case Transformation
388
+ | Shape | Used by |
389
+ | ----- | ------- |
390
+ | `masterRecordWire` / `searchMasterWire` | Upsert / Search master |
391
+ | `bookingFileWire` | CreateBooking, ModFileServices, ModFileHeader |
392
+ | `filePaymentListRequestWire` | InsertFilePaymentList (`paymentUser` root attr) |
393
+ | `searchFileWire` | SearchBookingFiles (date ranges / insurance attrs) |
394
+ | `setFileStatusWire` | SetBookingFileStatus |
395
+ | `packageDetailRequestWire` | GetPackageDetail |
396
+ | `baseSearchWire` + `avesSearchWire` | SearchAvesPackages / SearchTopServices |
397
+ | `elementOnlyWire` | CancelFile, SetFileServiceStatus, CommitPackage |
267
398
 
268
- The SDK automatically handles case transformation between your code and the API:
399
+ Editing CreateBooking shapes does not affect SearchFile or AvesSearch.
269
400
 
270
- - **Input**: Use camelCase (e.g., `recordCode`, `zipCode`)
271
- - **API**: Automatically converted to PascalCase with XML attributes (e.g., `@RecordCode`, `ZipCode`)
272
- - **Output**: Automatically converted back to camelCase
401
+ ---
273
402
 
274
- You never need to worry about case conversion or XML attribute prefixes - the SDK handles it all.
403
+ ## Architecture
275
404
 
276
- ## Type Safety
405
+ `AvesClient` (`src/client.ts`) is a thin facade over DI-friendly domain clients:
277
406
 
278
- All types are exported and inferred from the validation schemas:
407
+ | Module | Role |
408
+ | ------ | ---- |
409
+ | `AvesTransport` | HTTP + XML encode/decode + `invokeOp` (optional `bodyKey`) |
410
+ | `MasterRecordsClient` | search / upsert |
411
+ | `BookingClient` | booking file ops + search practices |
412
+ | `PackageCatalogClient` | package/program catalog |
413
+ | `client/types.ts` | `AvesClientDeps` / `AvesClientFlat` |
414
+ | `client/flat-aliases.ts` | bind flat compat methods from domain prototypes |
415
+ | `src/xml/` | XML root helpers + JSON ↔ XML |
416
+
417
+ Flat aliases (`client.createBooking`, …) are attached in the constructor — add a domain method once and both surfaces work.
418
+
419
+ Outbound path: validate → `createApiSchema` / `toWireBody` → `invokeOp` → XML POST.
420
+
421
+ ---
422
+
423
+ ## Types
279
424
 
280
425
  ```typescript
281
426
  import type {
427
+ AvesClientOptions,
428
+ AvesClientDeps,
429
+ SearchMasterRecord,
282
430
  SearchMasterRecordRS,
283
- ManageMasterRecordRS,
284
431
  MasterRecordDetail,
432
+ ManageMasterRecordRS,
433
+ BookingFileRQ,
434
+ BookingFileRS,
435
+ ModFileServicesRQ,
436
+ ModFileHeaderRQ,
437
+ CancelFileRQ,
438
+ SetFileStatusRQ,
439
+ SetFileServiceStatusRQ,
440
+ FilePaymentListRQ,
441
+ BookingStatusOnlyRS,
442
+ SearchBookingFileRQ,
443
+ SearchBookingFileRS,
444
+ AvesSearchRQ,
445
+ SearchPackageRS,
446
+ SearchServicesRS,
447
+ PackageDetailRQ,
448
+ PackageDetailRS,
449
+ CommitPackageRQ,
450
+ CommitPackageRS,
285
451
  } from 'aves-sdk';
286
452
 
287
- // Use types for your functions
288
- function processRecord(record: MasterRecordDetail) {
289
- // TypeScript knows all available fields in camelCase
290
- }
453
+ import {
454
+ AvesClient,
455
+ AvesTransport,
456
+ MasterRecordsClient,
457
+ BookingClient,
458
+ PackageCatalogClient,
459
+ AvesError,
460
+ } from 'aves-sdk';
291
461
  ```
292
462
 
293
- ## Validation
294
-
295
- The SDK validates all inputs and outputs using Valibot schemas:
296
-
297
- - **HostID**: Must be exactly 6 digits
298
- - **RecordCode**: Must be exactly 6 characters
299
- - **LanguageCode**: Must be exactly 2 digits (01=Italian, 02=English, etc.)
300
- - **Search parameters**: Required fields are enforced based on `searchType` using discriminated unions
301
- - All other fields follow the AVES API specification
302
-
303
- Invalid data will return an error `Result` 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`.
304
-
305
463
  ## License
306
464
 
307
465
  MIT
308
466
 
309
467
  ## Links
310
468
 
469
+ - [Changelog](./CHANGELOG.md)
311
470
  - [GitHub Repository](https://github.com/simoneguglielmi/aves-sdk)
312
471
  - [NPM Package](https://npmjs.com/package/aves-sdk)
313
472
  - [Issue Tracker](https://github.com/simoneguglielmi/aves-sdk/issues)