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