aves-sdk 1.0.3 → 1.1.1

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,19 +1,15 @@
1
- # AVES SDK for NestJS
1
+ # Aves SDK
2
2
 
3
- A comprehensive TypeScript SDK for integrating with the AVES XML REST API in NestJS applications. This SDK provides full type safety, validation, error handling, and follows NestJS best practices.
3
+ TypeScript SDK for integrating with the Aves XML 1.8.0 Booking API in NestJS applications. 100% type-safe, fully validated, and compliant with the official Aves XML specification.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Full NestJS Integration** - Native module with `forRoot`/`forRootAsync` support and global availability
8
- - **Complete Type Safety** - Comprehensive TypeScript interfaces with clean API abstractions
9
- - **Advanced Validation** - Modern Zod validation with `AvesValidator` class and utility functions
10
- - **Enhanced Date Handling** - Native JavaScript Date integration for robust date manipulation and validation
11
- - **Error Handling** - Structured error handling with AVES-specific error codes
12
- - **Configuration** - Environment-based configuration with validation
13
- - **Dependency Injection** - Interface-based DI following NestJS patterns
14
- - **Clean APIs** - Developer-friendly interfaces abstracting XML complexity
15
- - **Bidirectional Mappers** - Seamless conversion between clean and XML interfaces
16
- - **Production Ready** - Built for npm deployment with proper exports
7
+ - **100% Aves XML 1.8.0 Compliant** - Exact implementation of official spec
8
+ - **Full Type Safety** - Discriminated unions, type narrowing, zero `any` types
9
+ - **Smart Interfaces** - Type-safe search with discriminated unions
10
+ - **Zod Validation** - Runtime validation for all requests/responses
11
+ - **NestJS Native** - Proper module with DI support
12
+ - **Production Ready** - Tested, validated, optimized bundle
17
13
 
18
14
  ## Installation
19
15
 
@@ -29,48 +25,32 @@ bun add aves-sdk
29
25
 
30
26
  ## Quick Start
31
27
 
32
- ### 1. Environment Configuration
33
-
34
- Create a `.env` file:
28
+ ### 1. Configure Environment
35
29
 
36
30
  ```env
37
- AVES_BASE_URL=https://api.aves.example.com
31
+ AVES_BASE_URL=https://your-aves-instance.com
38
32
  AVES_HOST_ID=123456
39
- AVES_XTOKEN=your_xtoken_here
33
+ AVES_XTOKEN=your_token_here
40
34
  AVES_LANGUAGE_CODE=01
41
- AVES_TIMEOUT=30000
42
35
  ```
43
36
 
44
- ### 2. Module Setup
37
+ ### 2. Import Module
45
38
 
46
39
  ```typescript
47
40
  import { Module } from '@nestjs/common';
48
- import { ConfigModule } from '@nestjs/config';
41
+ import { ConfigModule, ConfigService } from '@nestjs/config';
49
42
  import { AvesModule } from 'aves-sdk';
50
43
 
51
44
  @Module({
52
45
  imports: [
53
- ConfigModule.forRoot({
54
- isGlobal: true,
55
- }),
56
- // Synchronous configuration
57
- AvesModule.forRoot({
58
- baseUrl: process.env.AVES_BASE_URL!,
59
- hostId: process.env.AVES_HOST_ID!,
60
- xtoken: process.env.AVES_XTOKEN!,
61
- languageCode: process.env.AVES_LANGUAGE_CODE,
62
- timeout: parseInt(process.env.AVES_TIMEOUT || '30000'),
63
- }),
64
-
65
- // OR Asynchronous configuration
46
+ ConfigModule.forRoot({ isGlobal: true }),
66
47
  AvesModule.forRootAsync({
67
48
  imports: [ConfigModule],
68
- useFactory: (configService: ConfigService) => ({
69
- baseUrl: configService.get('AVES_BASE_URL')!,
70
- hostId: configService.get('AVES_HOST_ID')!,
71
- xtoken: configService.get('AVES_XTOKEN')!,
72
- languageCode: configService.get('AVES_LANGUAGE_CODE'),
73
- timeout: configService.get('AVES_TIMEOUT'),
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'),
74
54
  }),
75
55
  inject: [ConfigService],
76
56
  }),
@@ -79,623 +59,350 @@ import { AvesModule } from 'aves-sdk';
79
59
  export class AppModule {}
80
60
  ```
81
61
 
82
- ### 3. Service Usage with Clean APIs
62
+ ### 3. Use the Service
83
63
 
84
64
  ```typescript
85
65
  import { Injectable } from '@nestjs/common';
86
- import {
87
- AvesService,
88
- SearchCustomerRequest,
89
- CreateBookingRequest,
90
- Customer,
91
- BookingResponse,
92
- } from 'aves-sdk';
66
+ import { AvesService, SearchCustomerRequest } from 'aves-sdk';
93
67
 
94
68
  @Injectable()
95
69
  export class BookingService {
96
- constructor(private readonly avesService: AvesService) {}
97
-
98
- async searchCustomers(searchTerm: string): Promise<Customer[]> {
99
- const searchRequest: SearchCustomerRequest = {
100
- type: 'customer',
101
- fields: [
102
- {
103
- name: 'LastName',
104
- value: searchTerm,
105
- operator: 'contains',
106
- },
107
- ],
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 },
108
78
  };
109
79
 
110
- const response = await this.avesService.searchCustomer(searchRequest);
111
- return response.results;
80
+ const result = await this.aves.searchCustomers(request);
81
+ return result.customers; // Fully typed Customer[]
112
82
  }
83
+ }
84
+ ```
113
85
 
114
- async createBooking(bookingData: {
115
- customerId: string;
116
- passengers: any[];
117
- services: any[];
118
- }): Promise<BookingResponse> {
119
- const bookingRequest: CreateBookingRequest = {
120
- type: 'individual',
121
- priority: 'normal',
122
- customerId: bookingData.customerId,
123
- passengers: bookingData.passengers,
124
- services: bookingData.services,
125
- };
86
+ ## Type-Safe Search (Discriminated Union)
126
87
 
127
- return await this.avesService.createBooking(bookingRequest);
128
- }
129
- }
88
+ The search interface uses **discriminated unions** for perfect type safety:
89
+
90
+ ```typescript
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
+ };
111
+
112
+ // Search by last modification date
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
+ };
130
119
  ```
131
120
 
132
- ## Clean API Interfaces
121
+ ### Available Search Types
133
122
 
134
- The SDK provides developer-friendly interfaces that abstract away XML complexity:
123
+ | Type | Required Fields | Optional Fields |
124
+ | ------------------- | ----------------- | ---------------------------------- |
125
+ | `code` | `code` | `pagination` |
126
+ | `name` | `name` | `city`, `pagination` |
127
+ | `vat_code` | `vatCode` | `phoneNumber`, `pagination` |
128
+ | `zone` | `zipCode` | `city`, `countyCode`, `pagination` |
129
+ | `category` | `categoryCode` | `pagination` |
130
+ | `email` | `email` | `pagination` |
131
+ | `last_mod_date` | `from`, `to` | `pagination` |
132
+ | `search_field` | `searchField` | `pagination` |
133
+ | `external_ref_code` | `externalRefCode` | `pagination` |
134
+
135
+ ## API Methods
135
136
 
136
137
  ### Customer Management
137
138
 
138
139
  ```typescript
139
- import {
140
- Customer,
141
- CustomerAddress,
142
- CustomerContact,
143
- AddressType,
144
- CustomerType,
145
- } from 'aves-sdk';
146
-
147
- // Clean, intuitive interfaces
148
- const customer: Customer = {
149
- id: '12345',
140
+ // Search customers
141
+ const result = await aves.searchCustomers({
142
+ type: 'name',
143
+ name: 'Rossi',
144
+ pagination: { pages: 25, page: 1 },
145
+ });
146
+
147
+ // Create customer
148
+ const customer = await aves.createCustomer({
149
+ id: '123456',
150
150
  type: 'customer',
151
- status: 'active',
151
+ status: 'enabled',
152
152
  personalInfo: {
153
- title: 'mr',
154
- firstName: 'John',
155
- lastName: 'Doe',
153
+ firstName: 'Mario',
154
+ lastName: 'Rossi',
156
155
  dateOfBirth: '1990-01-01',
157
156
  gender: 'male',
158
157
  },
159
- address: {
160
- type: 'home',
161
- street: '123 Main St',
162
- city: 'New York',
163
- postalCode: '10001',
164
- country: 'US',
165
- },
166
158
  contact: {
167
- phone: {
168
- type: 'mobile',
169
- number: '+1234567890',
170
- },
171
- email: {
172
- type: 'work',
173
- address: 'john.doe@example.com',
174
- },
159
+ email: { address: 'mario.rossi@example.com' },
160
+ phone: { number: '+39123456789' },
175
161
  },
176
- };
162
+ });
163
+
164
+ // Update customer
165
+ await aves.updateCustomer(customer);
166
+
167
+ // Upsert customer (insert or update secondary fields)
168
+ await aves.upsertCustomer(customer);
177
169
  ```
178
170
 
179
171
  ### Booking Management
180
172
 
181
173
  ```typescript
182
- import {
183
- CreateBookingRequest,
184
- BookingPassenger,
185
- BookingService,
186
- PassengerType,
187
- ServiceType,
188
- } from 'aves-sdk';
189
-
190
- const booking: CreateBookingRequest = {
191
- type: 'individual',
192
- priority: 'normal',
193
- customerId: '12345',
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',
194
181
  passengers: [
195
182
  {
196
- id: 'PAX001',
183
+ id: '001',
197
184
  type: 'adult',
198
- title: 'mr',
199
- firstName: 'John',
200
- lastName: 'Doe',
185
+ firstName: 'Mario',
186
+ lastName: 'Rossi',
201
187
  dateOfBirth: '1990-01-01',
202
188
  gender: 'male',
203
189
  },
204
190
  ],
205
191
  services: [
206
192
  {
207
- id: 'SRV001',
208
- type: 'flight',
209
- status: 'confirmed',
210
- description: 'Flight from NYC to LAX',
211
- startDate: '2024-06-01',
212
- endDate: '2024-06-01',
193
+ id: 'HTL001',
194
+ type: 'hotel',
195
+ status: 'pending',
196
+ name: 'Hotel Paradise',
197
+ startDate: '2025-07-01',
198
+ endDate: '2025-07-14',
213
199
  },
214
200
  ],
215
- };
216
- ```
217
-
218
- ### Complete Type Safety
219
-
220
- The SDK provides **zero `any` types** and complete type safety throughout:
221
-
222
- ```typescript
223
- import {
224
- CreateBookingRequest,
225
- Customer,
226
- CustomerAddress,
227
- CustomerContact,
228
- } from 'aves-sdk';
229
-
230
- // Fully type-safe customer details in booking
231
- const booking: CreateBookingRequest = {
232
- type: 'individual',
233
- priority: 'normal',
234
- customerId: '12345',
235
- // customerDetails is now properly typed as Customer interface
236
- customerDetails: {
237
- id: 'CUST001',
238
- type: 'customer',
239
- status: 'active',
240
- personalInfo: {
241
- title: 'mr',
242
- firstName: 'John',
243
- lastName: 'Doe',
244
- dateOfBirth: '1990-01-01',
245
- gender: 'male',
246
- },
247
- contact: {
248
- phone: {
249
- type: 'mobile',
250
- number: '+1234567890',
251
- },
252
- email: {
253
- type: 'work',
254
- address: 'john.doe@example.com',
255
- },
256
- },
257
- address: {
258
- type: 'home',
259
- street: '123 Main St',
260
- city: 'New York',
261
- postalCode: '10001',
262
- country: 'US',
263
- },
201
+ statisticCodes: {
202
+ code2: 'USA',
203
+ code3: 'GEN',
264
204
  },
265
- passengers: [...],
266
- services: [...],
267
- };
268
-
269
- // Automatic conversion to XML format with full type safety
270
- const xmlBooking = mapCreateBookingToXml(booking);
271
- ```
272
-
273
- ## API Reference
274
-
275
- ### Core Services
276
-
277
- #### AvesService
278
-
279
- The main service for interacting with the AVES API with clean interfaces.
280
-
281
- **Customer Management:**
282
-
283
- - `searchCustomer(request: SearchCustomerRequest)` - Search for customers
284
- - `createCustomer(customer: Customer)` - Create new customer
285
- - `updateCustomer(customer: Customer)` - Update existing customer
286
-
287
- **Booking Management:**
288
-
289
- - `createBooking(request: CreateBookingRequest)` - Create new booking
290
- - `updateBooking(bookingId: string, updates: Partial<CreateBookingRequest>)` - Update booking
291
- - `cancelBooking(request: CancelBookingRequest)` - Cancel booking
292
- - `getBooking(bookingId: string)` - Get booking details
293
-
294
- **Payment Management:**
295
-
296
- - `addPayment(request: AddPaymentRequest)` - Add payment to booking
297
- - `getPayments(bookingId: string)` - Get payment history
298
-
299
- **Document Management:**
300
-
301
- - `printDocument(request: PrintDocumentRequest)` - Generate documents
302
-
303
- #### AvesValidator
304
-
305
- Advanced validation class for comprehensive data validation scenarios.
306
-
307
- **Core Methods:**
308
-
309
- - `validate(data, schema?)` - Synchronous validation with error throwing
310
- - `asyncValidate(data, schema?)` - Asynchronous validation with error throwing
311
- - `safeValidateAndParse(data, schema?)` - Safe validation without throwing errors
312
- - `safeAsyncValidateAndParse(data, schema?)` - Safe async validation
313
-
314
- **Utility Methods:**
205
+ printDocument: false,
206
+ sendDocumentViaEmail: false,
207
+ });
315
208
 
316
- - `getErrorMessage(error, separator?)` - Format ZodError messages
317
- - `getSchema()` - Get current default schema
209
+ // Update booking header
210
+ await aves.updateBookingHeader('123456', 'BK/2025/001', '2025-07-01', {
211
+ notes: 'Updated booking notes',
212
+ passengers: [
213
+ /* updated passengers */
214
+ ],
215
+ });
318
216
 
319
- **Static Methods:**
217
+ // Set booking status
218
+ await aves.setBookingStatus('123456', 'BK/2025/001', 'confirmed');
320
219
 
321
- - `AvesValidator.withSchema(schema)` - Create validator with specific schema
220
+ // Cancel booking
221
+ await aves.cancelBooking({
222
+ bookingId: 'BK/2025/001',
223
+ customerId: '123456',
224
+ });
225
+ ```
322
226
 
323
- **Utility Functions:**
227
+ ### Document Management
324
228
 
325
- - `createValidator(schema)` - Create validator instance
326
- - Date utilities with native JavaScript Date for enhanced date manipulation
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
+ });
327
238
 
328
- ### Configuration
239
+ // Access generated documents
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
+ ```
329
246
 
330
- #### AvesSdkConfig
247
+ ### Payment Management
331
248
 
332
249
  ```typescript
333
- interface AvesSdkConfig {
334
- baseUrl: string; // AVES API base URL (validated as URL)
335
- hostId: string; // 6-digit host ID (validated)
336
- xtoken: string; // Authentication token (required)
337
- languageCode?: string; // Language code: '01' (Italian) or '02' (English)
338
- timeout?: number; // Request timeout in ms (default: 30000)
339
- }
250
+ // Add payment
251
+ await aves.addPayment({
252
+ bookingId: 'BK/2025/001',
253
+ payments: [
254
+ {
255
+ id: 'PAY001',
256
+ type: 'cash',
257
+ status: 'confirmed',
258
+ amount: {
259
+ currency: 'EUR',
260
+ amount: 500.0,
261
+ },
262
+ },
263
+ ],
264
+ enableMultiple: true,
265
+ operationType: 'absolute',
266
+ });
340
267
  ```
341
268
 
342
- ### Type Definitions
269
+ ## Type Definitions
343
270
 
344
- #### Union Types
345
-
346
- The SDK provides strongly-typed union types for better type safety:
271
+ ### Customer Types
347
272
 
348
273
  ```typescript
349
- type AddressType = 'home' | 'work' | 'billing' | 'delivery';
350
- type PassengerType = 'adult' | 'child' | 'infant';
351
- type ServiceType = 'flight' | 'hotel' | 'transfer' | 'activity';
352
- type PaymentType = 'cash' | 'credit_card' | 'bank_transfer';
353
- type CustomerType = 'customer' | 'agent' | 'supplier';
354
- type BookingType = 'individual' | 'group' | 'corporate';
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';
355
278
  ```
356
279
 
357
- #### Date Utilities
358
-
359
- Enhanced date manipulation with native JavaScript Date:
280
+ ### Booking Types
360
281
 
361
282
  ```typescript
362
- import {
363
- createDateString,
364
- createDateTimeString,
365
- createTimeString,
366
- formatDateString,
367
- isValidDateString,
368
- calculateAge,
369
- isValidBookingDate,
370
- } from 'aves-sdk';
371
-
372
- // Create validated date strings
373
- const dateString = createDateString('2024-01-01');
374
- const dateTimeString = createDateTimeString('2024-01-01T10:30:00');
375
- const timeString = createTimeString('10:30:00');
376
-
377
- // Format dates for display
378
- const formattedDate = formatDateString('2024-01-01', 'MMM dd, yyyy'); // "Jan 01, 2024"
379
-
380
- // Validate date strings
381
- const isValid = isValidDateString('2024-01-01'); // true
382
-
383
- // AVES-specific utilities
384
- const age = calculateAge('1990-01-01'); // Calculate customer age
385
- const isBookingValid = isValidBookingDate('2024-06-01'); // Check if booking date is valid
283
+ type BookingStatusType =
284
+ | 'quotation'
285
+ | 'work_in_progress'
286
+ | 'confirmed'
287
+ | 'optioned'
288
+ | 'nullified'
289
+ | 'canceled';
386
290
  ```
387
291
 
388
- ### Validation
389
-
390
- Built-in Zod validation with descriptive error messages:
292
+ ### Document Types
391
293
 
392
294
  ```typescript
393
- import { configValidationSchema } from 'aves-sdk';
394
-
395
- // Configuration validation
396
- const result = configValidationSchema.safeParse(config);
397
- if (!result.success) {
398
- console.error('Validation errors:', result.error.issues);
399
- }
400
-
401
- // Request validation
402
- import {
403
- SearchCustomerRequestValidation,
404
- CreateBookingRequestValidation,
405
- } from 'aves-sdk';
406
-
407
- const searchValidation =
408
- SearchCustomerRequestValidation.safeParse(searchRequest);
409
- const bookingValidation =
410
- CreateBookingRequestValidation.safeParse(bookingRequest);
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';
411
310
  ```
412
311
 
413
- #### AvesValidator Class
312
+ ## Response Interfaces
414
313
 
415
- The SDK provides a comprehensive `AvesValidator` class for advanced validation scenarios:
314
+ ### Search Response with Pagination
416
315
 
417
316
  ```typescript
418
- import {
419
- AvesValidator,
420
- configValidationSchema,
421
- createValidator,
422
- } from 'aves-sdk';
423
-
424
- // Constructor approach - validator with default schema
425
- const configValidator = new AvesValidator(configValidationSchema);
426
-
427
- // Synchronous validation with error throwing
428
- try {
429
- const validConfig = configValidator.validate(configData);
430
- console.log('Valid config:', validConfig);
431
- } catch (error) {
432
- if (error instanceof ZodError) {
433
- console.error('Validation errors:', configValidator.getErrorMessage(error));
434
- }
435
- }
436
-
437
- // Safe validation without throwing errors
438
- const result = configValidator.safeValidateAndParse(configData);
439
- if (result.success) {
440
- console.log('Valid config:', result.data);
441
- } else {
442
- console.error('Validation errors:', result.error.issues);
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
+ };
443
325
  }
444
-
445
- // Asynchronous validation
446
- const asyncResult = await configValidator.asyncValidate(configData);
447
-
448
- // Method approach - validator without default schema
449
- const validator = new AvesValidator();
450
-
451
- // Validate with different schemas
452
- const configResult = validator.validate(configData, configValidationSchema);
453
- const searchResult = validator.safeValidateAndParse(
454
- searchData,
455
- SearchCustomerRequestValidation
456
- );
457
-
458
- // Factory function approach
459
- const validator = createValidator(configValidationSchema);
460
- const result = validator.validate(configData);
461
326
  ```
462
327
 
463
- **AvesValidator Methods:**
464
-
465
- - `validate(data, schema?)` - Synchronous validation with error throwing
466
- - `asyncValidate(data, schema?)` - Asynchronous validation with error throwing
467
- - `safeValidateAndParse(data, schema?)` - Safe validation without throwing errors
468
- - `safeAsyncValidateAndParse(data, schema?)` - Safe async validation
469
- - `getErrorMessage(error, separator?)` - Format ZodError messages
470
- - `getSchema()` - Get current default schema
471
- - `setSchema(schema)` - Set new default schema
472
-
473
- ### Error Handling
474
-
475
- Structured error handling with AVES-specific error codes:
328
+ ### Document Print Result
476
329
 
477
330
  ```typescript
478
- import { AvesErrorHandler, AvesErrorCodes } from 'aves-sdk';
331
+ interface DocumentPrintResult {
332
+ emailRecipient?: string;
333
+ documents: PrintedDocument[];
334
+ additionalDocuments?: {
335
+ emailRecipient: string;
336
+ documents: PrintedDocument[];
337
+ }[];
338
+ }
479
339
 
480
- @Injectable()
481
- export class BookingService {
482
- constructor(
483
- private readonly avesService: AvesService,
484
- private readonly errorHandler: AvesErrorHandler
485
- ) {}
486
-
487
- async createBooking(data: CreateBookingRequest) {
488
- try {
489
- const response = await this.avesService.createBooking(data);
490
- return response;
491
- } catch (error) {
492
- const avesError = this.errorHandler.handleHttpError(error);
493
-
494
- switch (avesError.code) {
495
- case AvesErrorCodes.BOOKING_NOT_FOUND:
496
- throw new NotFoundException('Booking not found');
497
- case AvesErrorCodes.INVALID_REQUEST_FORMAT:
498
- throw new BadRequestException('Invalid booking data');
499
- case AvesErrorCodes.PAYMENT_FAILED:
500
- throw new PaymentRequiredException('Payment processing failed');
501
- default:
502
- throw new InternalServerErrorException(avesError.message);
503
- }
504
- }
505
- }
340
+ interface PrintedDocument {
341
+ fileName: string;
342
+ content?: string; // Base64 content
343
+ contentSize: number;
506
344
  }
507
345
  ```
508
346
 
509
- ## Advanced Usage
347
+ ## Validation
510
348
 
511
- ### Custom Configuration Factory
349
+ All requests are validated using Zod schemas:
512
350
 
513
351
  ```typescript
514
- @Injectable()
515
- export class CustomAvesConfigService implements AvesOptionsFactory {
516
- constructor(private configService: ConfigService) {}
517
-
518
- async createAvesOptions(): Promise<AvesSdkConfig> {
519
- // Custom logic to build configuration
520
- return {
521
- baseUrl: this.configService.get('AVES_BASE_URL')!,
522
- hostId: this.configService.get('AVES_HOST_ID')!,
523
- xtoken: await this.getTokenFromVault(),
524
- languageCode: '01',
525
- timeout: 60000,
526
- };
527
- }
352
+ import { searchCustomerRequestSchema } from 'aves-sdk';
528
353
 
529
- private async getTokenFromVault(): Promise<string> {
530
- // Custom token retrieval logic
531
- return 'your-secure-token';
532
- }
354
+ const result = searchCustomerRequestSchema.safeParse(request);
355
+ if (!result.success) {
356
+ console.error(result.error.issues);
533
357
  }
534
-
535
- // Use in module
536
- AvesModule.forRootAsync({
537
- useClass: CustomAvesConfigService,
538
- });
539
358
  ```
540
359
 
541
- ### Custom Error Interceptors
360
+ ## Error Handling
542
361
 
543
362
  ```typescript
544
- @Injectable()
545
- export class AvesErrorInterceptor implements NestInterceptor {
546
- constructor(private errorHandler: AvesErrorHandler) {}
547
-
548
- intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
549
- return next.handle().pipe(
550
- catchError((error) => {
551
- const avesError = this.errorHandler.handleHttpError(error);
552
-
553
- // Custom error mapping
554
- const httpStatus = this.mapAvesErrorToHttpStatus(avesError.code);
555
-
556
- throw new HttpException(
557
- {
558
- message: avesError.message,
559
- code: avesError.code,
560
- timestamp: avesError.timestamp,
561
- },
562
- httpStatus
563
- );
564
- })
565
- );
566
- }
567
-
568
- private mapAvesErrorToHttpStatus(code: string): number {
569
- const statusMap: Record<string, number> = {
570
- [AvesErrorCodes.BOOKING_NOT_FOUND]: 404,
571
- [AvesErrorCodes.INVALID_REQUEST_FORMAT]: 400,
572
- [AvesErrorCodes.PAYMENT_FAILED]: 402,
573
- };
363
+ import { AvesErrorHandler, AvesErrorCodes } from 'aves-sdk';
574
364
 
575
- return statusMap[code] || 500;
576
- }
365
+ try {
366
+ const booking = await aves.createBooking(request);
367
+ } catch (error) {
368
+ const avesError = errorHandler.handleHttpError(error);
369
+ console.error(avesError.code, avesError.message);
577
370
  }
578
371
  ```
579
372
 
580
- ### Type-Safe Mappers
581
-
582
- ```typescript
583
- import {
584
- mapCustomerToXml,
585
- mapCustomerFromXml,
586
- mapCreateBookingToXml,
587
- mapBookingFromXml,
588
- } from 'aves-sdk';
589
-
590
- // Convert clean API data to XML format
591
- const xmlCustomer = mapCustomerToXml(cleanCustomer);
592
- const xmlBooking = mapCreateBookingToXml(cleanBooking);
593
-
594
- // Convert XML response to clean API format
595
- const cleanCustomer = mapCustomerFromXml(xmlResponse);
596
- const cleanBooking = mapBookingFromXml(xmlResponse);
597
- ```
598
-
599
- ## Development
373
+ ## Bundle Size
600
374
 
601
- ### Building
375
+ Optimized for production:
602
376
 
603
- ```bash
604
- yarn build
605
- ```
377
+ - **ESM**: 51.75 KB (gzipped)
378
+ - **CJS**: 55.13 KB (gzipped)
379
+ - **DTS**: 137.03 KB
606
380
 
607
- ### Testing
381
+ ## Architecture
608
382
 
609
- ```bash
610
- yarn test
611
383
  ```
612
-
613
- ### Linting
614
-
615
- ```bash
616
- yarn lint
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
617
400
  ```
618
401
 
619
- ## Migration Guide
620
-
621
- ### From v0.x to v1.x
622
-
623
- The SDK has been completely rewritten with clean APIs and Zod validation:
624
-
625
- **Old (v0.x):**
626
-
627
- ```typescript
628
- // Complex XML interfaces
629
- const searchRequest: SearchMasterRecordRQ = {
630
- SearchCriteria: {
631
- MasterRecordType: 'CUSTOMER',
632
- SearchFields: {
633
- Field: [
634
- {
635
- '@Name': 'LastName',
636
- '@Value': 'Smith',
637
- '@Operator': 'CONTAINS',
638
- },
639
- ],
640
- },
641
- },
642
- };
643
- ```
644
-
645
- **New (v1.x):**
646
-
647
- ```typescript
648
- // Clean, developer-friendly interfaces
649
- const searchRequest: SearchCustomerRequest = {
650
- type: 'customer',
651
- fields: [
652
- {
653
- name: 'LastName',
654
- value: 'Smith',
655
- operator: 'contains',
656
- },
657
- ],
658
- };
659
- ```
660
-
661
- ## Contributing
662
-
663
- 1. Fork the repository
664
- 2. Create a feature branch
665
- 3. Make your changes
666
- 4. Add tests
667
- 5. Submit a pull request
668
-
669
402
  ## License
670
403
 
671
- MIT License - see LICENSE file for details.
672
-
673
- ## Support
674
-
675
- For issues and questions:
676
-
677
- - Create an issue on GitHub
678
- - Check the examples in `/examples` directory
679
- - Review the AVES technical documentation
680
-
681
- ## Changelog
682
-
683
- ### v1.0.0
684
-
685
- - **Clean API Interfaces** - Developer-friendly interfaces abstracting XML complexity
686
- - **Bidirectional Mappers** - Seamless conversion between clean and XML formats
687
- - **AvesValidator Class** - Comprehensive validation class with sync/async methods and utility functions
688
- - **Complete Type Safety** - Full TypeScript coverage with comprehensive interfaces for both clean API objects and XML structures, ensuring type safety throughout the entire request/response lifecycle
689
- - **Customer Mapper** - Full `Customer` to `MasterRecord` conversion with `mapCustomerToXml`
690
- - **Global Module** - NestJS global module for application-wide availability
691
- - **Enhanced Error Handling** - Structured error handling with AVES-specific codes
692
- - **Comprehensive Documentation** - Complete API reference and examples
693
- - **Production Ready** - Enterprise-grade implementation following NestJS best practices
404
+ MIT
694
405
 
695
- ### Breaking Changes from v0.x
406
+ ## Credits
696
407
 
697
- - Replaced `class-validator` with Zod validation
698
- - Introduced clean API interfaces alongside XML interfaces
699
- - Enhanced date utilities with native JavaScript Date
700
- - Updated module configuration with enhanced validation
701
- - Improved error handling structure
408
+ Built for the Aves XML 1.8.0 Booking CPX API specification.