sabre-client 0.2.4 → 0.3.0-next.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/air/search.ts","../src/air/ticketing.ts","../src/authentication/authentication.ts","../src/booking-management/booking.ts","../src/booking-management/flight-tickets.ts","../package.json","../src/config.ts","../src/errors.ts","../src/trip-management/reservation.ts","../src/sabre.ts"],"sourcesContent":["import { Sabre } from \"../sabre\"\nimport { BargainFinderMaxOptions, BargainFinderMaxResponseSuccess, RevalidateItineraryOptions, RevalidateItineraryResponseSuccess } from \"./interfaces\";\n\nexport class Search {\n /**\n * Bargain Finder Max v5\n * \n * Bargain Finder Max (BFM), \n * nuestro producto de búsqueda de tarifas bajas líder en su clase, \n * se utiliza para buscar los itinerarios con los precios más bajos disponibles según una fecha específica.\n * \n * Revalidate Itinerary v5\n * \n * La API Revalidate Itinerary permite volver a consultar la disponibilidad \n * y el precio de una opción de itinerario específica sin tener que reservarla. \n * La solución revalida si la opción de itinerario es válida para la compra. \n * Revalidate Itinerary no admite contenido NDC.\n * \n * @param sabre Sabre Client Reference\n */\n constructor (\n private sabre: Sabre\n ) {}\n\n /**\n * Crear solicitud de Buscador de ofertas Max.\n * \n * payload - El mensaje de solicitud de búsqueda de tarifa baja solicita opciones \n * de itinerario para vuelos entre pares de ciudades específicos, en fechas específicas, \n * para un número y tipo de pasajeros específicos. \n * La información opcional de la solicitud puede incluir: \n * hora/ventana horaria, ciudades de conexión \n * y preferencias del cliente (aerolíneas, cabina, tipo de vuelo, etc.). \n * La solicitud de búsqueda de tarifa baja contiene información similar a \n * la de una búsqueda de tarifa baja en el CRS o GDS de una aerolínea.\n * @param payload BargainFinderMaxOptions \n * @returns {Promise<BargainFinderMaxResponseSuccess>}\n */\n async shop(payload: BargainFinderMaxOptions): Promise<BargainFinderMaxResponseSuccess> {\n const path = \"/v5/offers/shop\";\n return this.sabre.post<BargainFinderMaxResponseSuccess>(path, payload)\n }\n /**\n * Crear solicitud de revalidación de itinerario.\n * \n * payload - El mensaje de solicitud de búsqueda de tarifa baja solicita opciones\n * de itinerario para vuelos entre pares de ciudades específicos, en fechas específicas, \n * para un número y tipo de pasajeros específicos. \n * La información opcional de la solicitud puede incluir: \n * hora/ventana horaria, ciudades de conexión \n * y preferencias del cliente (aerolíneas, cabina, tipo de vuelo, etc.). \n * La solicitud de búsqueda de tarifa baja contiene información similar a \n * la de una búsqueda de tarifa baja en el CRS o GDS de una aerolínea.\n * @param payload RevalidateItineraryOptions\n * @returns {Promise<RevalidateItineraryResponseSuccess>}\n */\n async revalidate(payload: RevalidateItineraryOptions): Promise<RevalidateItineraryResponseSuccess> {\n const path = \"/v5/shop/flights/revalidate\";\n return this.sabre.post<RevalidateItineraryResponseSuccess>(path, payload)\n }\n}","import { Sabre } from \"../sabre\"\nimport { EnhancedAirTicketOptions, EnhancedAirTicketResponseSuccess } from \"./interfaces\";\n\nexport class Ticketing {\n /**\n * Enhanced Air Ticket v1.3.0\n * \n * La API de boletos aéreos mejorados se utiliza para emitir uno o varios boletos aéreos \n * y/o EMD (documentos electrónicos varios) dentro de una sola llamada API.\n * \n * @param sabre Sabre Client Reference\n */\n constructor (\n private sabre: Sabre\n ) {}\n\n /**\n * La API de boletos aéreos mejorados (AirTicketRQ) \n * se utiliza para emitir boletos aéreos y documentos electrónicos varios (EMD) en una sola solicitud.\n * \n * payload - Solicitud de API de boletos aéreos orquestada.\n * @param payload EnhancedAirTicketOptions \n * @returns {Promise<EnhancedAirTicketResponseSuccess>}\n */\n async issue(payload: EnhancedAirTicketOptions): Promise<EnhancedAirTicketResponseSuccess> {\n const path = \"/v1.3.0/air/ticket\";\n return this.sabre.post<EnhancedAirTicketResponseSuccess>(path, payload)\n }\n}","import { Sabre } from \"../sabre\";\nimport { CreateTokenResponseSuccess } from \"./interfaces\";\n\nconst grantType = new URLSearchParams({ 'grant_type': 'client_credentials' }).toString()\n\nexport class Authentication {\n constructor(private readonly sabre: Sabre) {}\n /**\n * OAuth Token Create REST API v2\n * See https://developer.sabre.com/docs/rest_apis/session_management/token_create_api/v2\n * @param payload El tipo de concesión utilizado para obtener el token. Sólo se admiten 'client_credentials'.\n * @returns TokenResponse\n */\n async OAuthTokenV2(\n payload: string = grantType\n ): Promise<CreateTokenResponseSuccess> {\n const data = await this.sabre.auth<CreateTokenResponseSuccess>(\n '/v2/auth/token',\n payload\n );\n this.sabre.setAuthorization(data.access_token)\n return data\n }\n}","import { Sabre } from \"../sabre\"\nimport {\n CancelBookingOptions,\n CancelBookingResponseSuccess,\n CreateBookingOptions,\n CreateBookingResponseSuccess,\n GetBookingOptions,\n GetBookingResponseSuccess,\n ModifyBookingOptions,\n ModifyBookingResponseSuccess,\n} from \"./interfaces\"\n\nexport class Booking {\n /**\n * Booking\n * \n * La API de reservas está diseñada para proporcionar una vista normalizada de una reserva de Sabre combinando el PNR de Sabre y el pedido de Sabre.\n * \n * @param sabre Sabre Client Reference\n */\n constructor (\n private sabre: Sabre\n ) {}\n /**\n * Crea una solicitud que contiene un \"Id. de confirmación\" y un \"apellido\" del viajero para obtener información de la reserva.\n * \n * payload - Contiene elementos tanto obligatorios como opcionales para realizar una solicitud de reserva.\n * @param payload GetBookingOptions\n * @returns {Promise<GetBookingResponseSuccess>}\n */\n get(payload: GetBookingOptions): Promise<GetBookingResponseSuccess>{\n const path = '/v1/trip/orders/getBooking'\n return this.sabre.post<GetBookingResponseSuccess>(path, payload)\n }\n /**\n * Crea una reserva aérea (NDC/ATPCO/LCC).\n * \n * payload - Contiene elementos obligatorios y opcionales para realizar una solicitud de reserva.\n * @param payload CreateBookingOptions\n * @returns {Promise<CreateBookingResponseSuccess>}\n */\n async create(payload: CreateBookingOptions): Promise<CreateBookingResponseSuccess> {\n const path = '/v1/trip/orders/createBooking'\n return this.sabre.post<CreateBookingResponseSuccess>(path, payload)\n }\n /**\n * Crea una lista de elementos de reserva que deben cancelarse.\n * \n * payload - Contiene elementos obligatorios y opcionales para cancelar la totalidad o partes de una reserva.\n * @param payload CancelBookingOptions\n * @returns {Promise<CancelBookingResponseSuccess>}\n */\n async cancel(payload: CancelBookingOptions): Promise<CancelBookingResponseSuccess> {\n const path = '/v1/trip/orders/cancelBooking'\n return this.sabre.post<CancelBookingResponseSuccess>(path, payload)\n }\n /**\n * Crea una lista de elementos de reserva que deben modificarse.\n * \n * payload - Contiene elementos obligatorios y opcionales para modificar datos no relacionados con el itinerario en la reserva existente. \n * @param payload ModifyBookingOptions \n * @returns {Promise<ModifyBookingResponseSuccess>}\n */\n async modify(payload: ModifyBookingOptions): Promise<ModifyBookingResponseSuccess> {\n const path = '/v1/trip/orders/modifyBooking'\n return this.sabre.post<ModifyBookingResponseSuccess>(path, payload)\n }\n\n}","import { Sabre } from \"../sabre\"\nimport {\n CheckTicketsOptions,\n CheckTicketsResponseSuccess,\n FulfillTicketsOptions,\n FulfillTicketsResponseSuccess,\n RefundTicketsOptions,\n RefundTicketsResponseSuccess,\n VoidTicketsOptions,\n VoidTicketsResponseSuccess,\n} from \"./interfaces\"\n\nexport class FlightTickets {\n /**\n * Flight Tickets\n * \n * Los endpoint de Flight Tickets son un conjunto de métodos diseñados para obtener detalles de los billetes y \n * realizar operaciones específicas (anulación/reembolso) sobre ellos.\n * \n * @param sabre Sabre Client Reference\n */\n constructor (\n private sabre: Sabre\n ) {}\n\n /**\n * Procesa tickets proporcionando una solicitud que contiene una lista de números de ticket que se anularán.\n * \n * payload - Contiene elementos obligatorios y opcionales para anular los billetes.\n * @param payload VoidTicketsOptions\n * @returns {Promise<VoidTicketsResponseSuccess>}\n */\n async void(payload: VoidTicketsOptions): Promise<VoidTicketsResponseSuccess> {\n const path = '/v1/trip/orders/voidFlightTickets'\n return this.sabre.post<VoidTicketsResponseSuccess>(path, payload)\n }\n\n /**\n * Procesa los boletos proporcionando una solicitud que contiene una lista de números de boletos que deben reembolsarse. \n * Actualmente, los EMD no son compatibles.\n * \n * payload - Contiene elementos obligatorios y opcionales para el reembolso de los billetes.\n * @param payload RefundTicketsOptions\n * @returns {Promise<RefundTicketsResponseSuccess>}\n */\n async refund(payload: RefundTicketsOptions): Promise<RefundTicketsResponseSuccess> {\n const path = '/v1/trip/orders/refundFlightTickets'\n return this.sabre.post<RefundTicketsResponseSuccess>(path, payload)\n }\n \n /**\n * Procesa tickets proporcionando una solicitud que contiene una lista de números de ticket que se verificarán. \n * Actualmente, los EMD no son compatibles.\n * \n * payload - Contiene elementos obligatorios y opcionales para consultar los tickets.\n * @param payload CheckTicketsOptions\n * @returns {Promise<CheckTicketsResponseSuccess>} CheckTicketsResponse\n */\n async check(payload: CheckTicketsOptions): Promise<CheckTicketsResponseSuccess> {\n const path = '/v1/trip/orders/checkFlightTickets'\n return this.sabre.post<CheckTicketsResponseSuccess>(path, payload)\n }\n\n /**\n * Procesa la emisión de billetes y documentos varios electrónicos (EMD).\n * Actualmente, los EMD no son compatibles.\n * \n * payload - Contiene elementos obligatorios y opcionales para la emisión de billetes.\n * @param payload FulfillTicketsOptions\n * @returns {Promise<FulfillTicketsResponseSuccess>}\n */\n async fulfill(payload: FulfillTicketsOptions): Promise<FulfillTicketsResponseSuccess> {\n const path = '/v1/trip/orders/fulfillFlightTickets'\n return this.sabre.post<FulfillTicketsResponseSuccess>(path, payload)\n }\n}","{\n \"name\": \"sabre-client\",\n \"version\": \"0.2.4\",\n \"description\": \"Sabre Node.js SDK\",\n \"keywords\": [\n \"sabre\",\n \"client\",\n \"devStudio\",\n \"rest\"\n ],\n \"homepage\": \"https://github.com/CarlosIvanSoto/sabre#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/CarlosIvanSoto/sabre/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/CarlosIvanSoto/sabre.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"Carlos Ivan Soto <csoto_99@outlook.com>\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist/**\"\n ],\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"jest --passWithNoTests\",\n \"test:watch\": \"jest --watch\",\n \"lint\": \"eslint . --ext .ts --report-unused-disable-directives --max-warnings 0\",\n \"type-check\": \"tsc --noEmit\",\n \"example:auth-atk\": \"node --env-file=.env --import=tsx examples/auth-atk.ts\",\n \"example:search-shop\": \"node --env-file=.env --import=tsx examples/search-shop.ts\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.38.0\",\n \"@types/jest\": \"^30.0.0\",\n \"@types/node\": \"^24.8.1\",\n \"eslint\": \"^9.38.0\",\n \"jest\": \"^30.2.0\",\n \"ts-jest\": \"^29.4.5\",\n \"ts-node\": \"^10.9.2\",\n \"tsup\": \"^8.5.0\",\n \"tsx\": \"^4.20.6\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.46.1\"\n }\n}\n","import { version } from '../package.json';\n\nconst defaultBaseUrl = 'https://api.platform.sabre.com';\nconst defaultUserAgent = `sabre-client-node:${version}`;\nconst defaultConversationId = `sabre.client.node:${version}`\nconst defaultDomain = 'AA'\n\nconst baseUrl =\n typeof process !== 'undefined' && process.env\n ? process.env.SABRE_REST_URL || defaultBaseUrl\n : defaultBaseUrl;\n\nconst userAgent =\n typeof process !== 'undefined' && process.env\n ? process.env.SABRE_USER_AGENT || defaultUserAgent\n : defaultUserAgent;\n\nconst domain =\n typeof process !== 'undefined' && process.env\n ? process.env.SABRE_DOMAIN || defaultDomain\n : defaultDomain;\n\nconst conversationId = \n typeof process !== 'undefined' && process.env\n ? process.env.SABRE_CONVERSATION_ID || defaultConversationId\n : defaultConversationId\n \nexport { baseUrl, userAgent, domain, conversationId };","/**\n * Clase de error personalizada para los errores de la API de Sabre.\n * Extiende la clase Error nativa para proporcionar más contexto.\n */\nexport class SabreError extends Error {\n public readonly details: string;\n public readonly statusCode: number;\n\n constructor(message: string, statusCode: number, details: string) {\n super(message);\n this.name = 'SabreError';\n this.statusCode = statusCode;\n this.details = details;\n }\n}","import { Sabre } from \"../sabre\"\nimport { CreatePassengerNameRecordOptions, CreatePassengerNameRecordResponseSuccess } from \"./interfaces\"\n\nexport class Reservation {\n /**\n * Reservation\n * \n * La API para crear un registro de nombre de pasajero es una API \n * orquestada que integra varias funciones y operaciones en una sola llamada.\n * \n * Esta API permite crear un registro de nombre de pasajero (PNR), \n * incluyendo segmentos aéreos, en una sola llamada.\n * \n * @param sabre Sabre Client Reference\n */\n constructor (\n private sabre: Sabre\n ) {}\n /**\n * Cree una reserva completa de contenido aéreo, hotel y automóvil de alquiler, todo dentro de una sola solicitud.\n * \n * payload - Contiene elementos obligatorios y opcionales para realizar una solicitud de reserva.\n * @param payload CreatePassengerNameRecordOptions\n * @returns {Promise<CreatePassengerNameRecordResponseSuccess>}\n */\n create(payload: CreatePassengerNameRecordOptions): Promise<CreatePassengerNameRecordResponseSuccess> {\n const path = '/v2.5.0/passenger/records?mode=create'\n return this.sabre.post<CreatePassengerNameRecordResponseSuccess>(path, payload)\n }\n\n}","import { Search, Ticketing } from \"./air\";\nimport { Authentication } from \"./authentication/authentication\";\nimport { Booking, FlightTickets } from \"./booking-management\";\nimport { PostOptions } from \"./common/interfaces\";\nimport { baseUrl, conversationId, domain, userAgent } from \"./config\";\nimport { SabreError } from \"./errors\";\nimport { SabreOptions } from \"./interfaces\";\nimport { Reservation } from \"./trip-management/reservation\";\n\nexport class Sabre {\n private readonly headers: Headers;\n private readonly secret: string;\n\n readonly authentication = new Authentication(this)\n readonly booking = new Booking(this)\n readonly flightTickets = new FlightTickets(this)\n readonly search = new Search(this)\n readonly ticketing = new Ticketing(this)\n readonly reservation = new Reservation(this)\n\n constructor(private readonly options: SabreOptions = {}) {\n const processEnv = typeof process !== 'undefined' && process.env\n if (!this.options.username && processEnv)\n this.options.username = processEnv.SABRE_USERNAME\n if (!this.options.password && processEnv)\n this.options.password = processEnv.SABRE_PASSWORD\n if (!this.options.organization && processEnv)\n this.options.organization = processEnv.SABRE_ORGANIZATION\n\n if (!this.options.username || !this.options.password || !this.options.organization) {\n throw new Error(`Missing Sabre authorization. Pass it to the constructor new Sabre({\n username: '773400', \n password: 'PASSWORD_GOES_HERE',\n organization: '7TZA', // pcc\n });})`)\n }\n\n this.headers = new Headers({\n 'User-Agent': userAgent,\n 'Conversation-ID': conversationId\n });\n\n this.secret = this.getSecret()\n }\n\n setAuthorization(token: string): void {\n this.headers.set('Authorization', `Bearer ${token}`)\n this.headers.set('Content-Type', 'application/json')\n }\n\n async fetchRequest<T>(\n path: string,\n options = {},\n ): Promise<T> {\n const response = await fetch(`${baseUrl}${path}`, options);\n \n if (!response.ok) {\n let errorDetails = `Request failed with status ${response.status}`;\n try {\n const jsonError = await response.json() as unknown;\n errorDetails = JSON.stringify(jsonError);\n } catch (e) {\n console.error(e)\n errorDetails = response.statusText;\n }\n throw new SabreError(\n `Request failed with status ${response.status}`, \n response.status, \n errorDetails);\n }\n\n const data = await response.json() as T;\n return data;\n }\n async post<T>(path: string, entity?: unknown, options: PostOptions = {}): Promise<T> {\n const requestOptions = {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify(entity),\n ...options,\n };\n\n return this.fetchRequest<T>(path, requestOptions);\n }\n\n async auth<T>(path: string, entity?: unknown, options: PostOptions = {}): Promise<T> {\n /**\n * La palabra 'basic' seguida de un EPR codificado en base64 \n * como par base64(base64(V1:usuario:grupo:dominio):base64(contraseña)), \n * p.e. basic VmpFNmRYTmxjbWxrT21keWIzVndPbVJ2YldGcGJnPT06TVRJek5EVT0=\n */\n this.headers.set('Authorization', `Basic ${this.secret}`)\n this.headers.set('Content-Type', 'application/x-www-form-urlencoded')\n\n const requestOptions = {\n method: 'POST',\n headers: this.headers,\n body: entity,\n ...options,\n };\n\n return this.fetchRequest<T>(path, requestOptions);\n }\n\n private getSecret(): string {\n if (!this.options.password) throw new Error('Missing Sabre password')\n return btoa(`${this.userID()}:${btoa(this.options.password)}`)\n }\n private userID(): string {\n return btoa(`V1:${this.options.username}:${this.options.organization}:${domain}`)\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors/sabre-error.ts","../src/air/grouped-itinerary.ts","../src/air/itinerary-messages.ts","../src/air/bargain-finder-max.ts","../src/air/itinerary-flights.ts","../src/air/revalidate-itinerary.ts","../src/air/air.ts","../src/logging/redact.ts","../src/logging/logger.ts","../src/auth/token-request.ts","../src/auth/token-store.ts","../src/auth/auth-manager.ts","../src/booking/booking-errors.ts","../src/booking/cancel-booking.ts","../src/booking/create-booking.ts","../src/booking/get-booking.ts","../src/booking/booking-management.ts","../src/http/retry.ts","../src/config.ts","../src/http/rest-transport.ts","../src/sabre.ts","../src/booking/flight-details.ts","../src/index.ts"],"sourcesContent":["// Jerarquía de errores del SDK. Ver sabre-wiki/wiki/sdk/manejo-y-mapeo-de-errores.md.\n\nexport interface SabreErrorOptions {\n /** Si la política de reintentos puede volver a intentar la operación. */\n retryable: boolean;\n /** Fragmento de la respuesta original sin transformar (JSON parseado o nodo XML). */\n raw?: unknown;\n cause?: unknown;\n}\n\n/**\n * Base de todos los errores del SDK.\n *\n * `raw` puede contener credenciales o datos de pasajero: no es enumerable, así que\n * no aparece en `JSON.stringify`, spreads ni serializadores de logs, pero sigue\n * accesible como `error.raw` para debugging. No lo vuelques a un logger sin sanitizar.\n */\nexport class SabreError extends Error {\n override name = 'SabreError';\n readonly retryable: boolean;\n declare readonly raw: unknown;\n\n constructor(message: string, options: SabreErrorOptions) {\n super(message, options.cause === undefined ? undefined : { cause: options.cause });\n this.retryable = options.retryable;\n Object.defineProperty(this, 'raw', {\n value: options.raw,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n }\n\n toJSON(): Record<string, unknown> {\n const fields: Record<string, unknown> = Object.fromEntries(Object.entries(this));\n return { ...fields, name: this.name, message: this.message };\n }\n}\n\nexport type SabreProtocol = 'rest' | 'soap';\n\nexport interface SabreGatewayErrorOptions extends SabreErrorOptions {\n protocol: SabreProtocol;\n /** HTTP status de la respuesta, si la hubo. */\n status?: number;\n /** Código tal cual lo devuelve el gateway (`ERR.2SG.*`, `USG_*`), si viene en el body. */\n code?: string;\n}\n\n/** Error de transporte/gateway (`ERR.2SG.*` + HTTP status en REST, `USG_*` en SOAP). */\nexport class SabreGatewayError extends SabreError {\n override name = 'SabreGatewayError';\n readonly protocol: SabreProtocol;\n readonly status: number | undefined;\n readonly code: string | undefined;\n\n constructor(message: string, options: SabreGatewayErrorOptions) {\n super(message, options);\n this.protocol = options.protocol;\n this.status = options.status;\n this.code = options.code;\n }\n}\n\nexport interface SabreOrchestrationErrorOptions extends Omit<SabreErrorOptions, 'retryable'> {\n /** `SP.PROVIDER_ERROR` o `SP.INTERNAL_ERROR`. */\n code: string;\n}\n\n/**\n * Error de servicio orquestado (`SP.*`), viaja dentro de una respuesta 200.\n * `SP.PROVIDER_ERROR` es reintentable; `SP.INTERNAL_ERROR` (y cualquier otro) no.\n */\nexport class SabreOrchestrationError extends SabreError {\n override name = 'SabreOrchestrationError';\n readonly code: string;\n\n constructor(message: string, options: SabreOrchestrationErrorOptions) {\n super(message, { ...options, retryable: options.code === 'SP.PROVIDER_ERROR' });\n this.code = options.code;\n }\n}\n\nexport interface SabreServiceErrorOptions extends Omit<SabreErrorOptions, 'retryable'> {\n /** Servicio que originó el error, p. ej. `'createBooking'`. */\n service: string;\n /** Código tal cual lo documenta Sabre, sin normalizar. */\n code: string;\n}\n\nexport interface SabreBusinessErrorOptions extends SabreServiceErrorOptions {\n /**\n * Solo para códigos que Sabre documenta como temporales en un servicio de lectura\n * (p. ej. `Transmission timeout` de Bargain Finder Max). Por defecto `false`.\n * La política de reintentos igual exige que la operación sea idempotente.\n */\n retryable?: boolean;\n /** Avisos que llegaron junto con el error (p. ej. `category: WARNING` de Create Booking). */\n warnings?: readonly SabreWarning[];\n /**\n * Otros errores que llegaron junto con este (p. ej. la causa real detrás de\n * `NO_ITEMS_CANCELLED` en Cancel Booking).\n */\n errors?: readonly SabreBusinessError[];\n}\n\n/**\n * Error del catálogo propio de un servicio. No es reintentable, salvo los códigos\n * temporales de servicios de lectura que se marcan con `retryable: true`.\n */\nexport class SabreBusinessError extends SabreError {\n override name = 'SabreBusinessError';\n readonly service: string;\n readonly code: string;\n readonly warnings: readonly SabreWarning[];\n readonly errors: readonly SabreBusinessError[];\n\n constructor(message: string, options: SabreBusinessErrorOptions) {\n super(message, { ...options, retryable: options.retryable ?? false });\n this.service = options.service;\n this.code = options.code;\n this.warnings = options.warnings ?? [];\n this.errors = options.errors ?? [];\n }\n}\n\n/**\n * Advertencia de un servicio (p. ej. `category: WARNING` de Create Booking, soft errors\n * de End Transaction): no es un fallo fatal. Nunca se reintenta automáticamente.\n */\nexport class SabreWarning extends SabreError {\n override name = 'SabreWarning';\n readonly service: string;\n readonly code: string;\n\n constructor(message: string, options: SabreServiceErrorOptions) {\n super(message, { ...options, retryable: false });\n this.service = options.service;\n this.code = options.code;\n }\n}\n","// Modelo `groupedItineraryResponse` compartido por Bargain Finder Max y Revalidate Itinerary,\n// y su desnormalizador: resuelve cada `ref` al objeto completo antes de exponerlo.\n// Ver sabre-wiki/wiki/concepts/modelo-de-itinerario.md.\n//\n// Sin schema formal: los campos salen de los ejemplos de BFM y Revalidate del wiki. Los que\n// solo aparecieron en uno de los dos van como opcionales.\nimport { SabreError } from '../errors/index.js';\n\n// ---------------------------------------------------------------------------\n// Descriptores compartidos (arrays planos indexados por `id`)\n// ---------------------------------------------------------------------------\n\nexport interface ScheduleEndpoint {\n airport: string;\n city?: string;\n /** Visto en sandbox para aeropuertos de EE. UU. */\n state?: string;\n country?: string;\n /** Hora local con offset, p. ej. `17:10:00+02:00`. */\n time: string;\n terminal?: string;\n /** Días que se suman a la fecha de salida del vuelo. Visto en sandbox (`arrival`). */\n dateAdjustment?: number;\n}\n\nexport interface ScheduleEquipment {\n code: string;\n typeForFirstLeg?: string;\n typeForLastLeg?: string;\n}\n\nexport interface ScheduleCarrier {\n marketing: string;\n marketingFlightNumber: number;\n operating?: string;\n operatingFlightNumber?: number;\n alliances?: string;\n equipment?: ScheduleEquipment;\n}\n\n/** Vuelo/segmento operado (`scheduleDescs[]`). */\nexport interface ScheduleDesc {\n id: number;\n /** Visto en sandbox, p. ej. `\"7\"`; significado sin confirmar. */\n dotRating?: string;\n frequency?: string;\n stopCount?: number;\n eTicketable?: boolean;\n totalMilesFlown?: number;\n /** Minutos. */\n elapsedTime?: number;\n departure: ScheduleEndpoint;\n arrival: ScheduleEndpoint;\n carrier: ScheduleCarrier;\n}\n\n/** Tramo lógico (`legDescs[]`): agrupa schedules por `ref`. */\nexport interface LegDesc {\n id: number;\n /** Minutos. */\n elapsedTime?: number;\n schedules: LegScheduleRef[];\n}\n\n/**\n * Schedule dentro de un tramo. `departureDateAdjustment`: días que se suman a la fecha del\n * tramo para la salida de este vuelo (conexión al día siguiente). Visto en sandbox, sin\n * documentar en los ejemplos de Sabre.\n */\nexport interface LegScheduleRef extends Ref {\n departureDateAdjustment?: number;\n}\n\n/** Impuesto individual (`taxDescs[]`). */\nexport interface TaxDesc {\n id: number;\n code: string;\n amount: number;\n currency: string;\n description?: string;\n publishedAmount?: number;\n publishedCurrency?: string;\n station?: string;\n country?: string;\n /** Visto en sandbox. */\n taxReissue?: { refundable?: boolean };\n}\n\n/** Resumen de impuestos por código (`taxSummaryDescs[]`). Misma forma que `TaxDesc`. */\nexport type TaxSummaryDesc = TaxDesc;\n\n/** Cargo adicional (`obFeeDescs[]`). Significado exacto de \"OB\" sin confirmar. */\nexport interface ObFeeDesc {\n id: number;\n amount: number;\n currency: string;\n}\n\nexport interface FareComponentDescSegment {\n segment: {\n stopover?: boolean;\n };\n}\n\n/** Componente de tarifa (`fareComponentDescs[]`). */\nexport interface FareComponentDesc {\n id: number;\n governingCarrier?: string;\n fareAmount?: number;\n fareCurrency?: string;\n fareBasisCode: string;\n farePassengerType?: string;\n publishedFareAmount?: number;\n publishedFareCurrency?: string;\n /** `FROM` / `TO`. */\n directionality?: string;\n applicablePricingCategories?: string;\n vendorCode?: string;\n fareTypeBitmap?: string;\n fareType?: string;\n fareTariff?: string;\n fareRule?: string;\n cabinCode?: string;\n segments?: FareComponentDescSegment[];\n // Vistos solo en Revalidate Itinerary.\n ticketDesignator?: string;\n mileageSurcharge?: number;\n mileage?: boolean;\n oneWayFare?: boolean;\n negotiatedFare?: boolean;\n privateFare?: boolean;\n notValidAfter?: string;\n /** Distinto de `directionality`; significado sin confirmar. */\n direction?: string;\n}\n\n/** Aerolínea validadora (`validatingCarrierDescs[]`). */\nexport interface ValidatingCarrierDesc {\n id: number;\n settlementMethod?: string;\n newVcxProcess?: boolean;\n default?: { code: string };\n}\n\n/** Franquicia de equipaje (`baggageAllowanceDescs[]`). */\nexport interface BaggageAllowanceDesc {\n id: number;\n pieceCount?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Piezas que no llevan referencias\n// ---------------------------------------------------------------------------\n\n/** Referencia a un descriptor por su `id`. */\nexport interface Ref {\n ref: number;\n}\n\nexport interface ItineraryMessage {\n severity: string;\n type: string;\n code: string;\n text: string;\n}\n\nexport interface LegDescription {\n departureDate: string;\n departureLocation: string;\n arrivalLocation: string;\n}\n\nexport interface CurrencyConversion {\n from: string;\n to: string;\n exchangeRateUsed: number;\n}\n\nexport interface PassengerTotalFare {\n totalFare: number;\n totalTaxAmount?: number;\n currency: string;\n baseFareAmount?: number;\n baseFareCurrency?: string;\n equivalentAmount?: number;\n equivalentCurrency?: string;\n constructionAmount?: number;\n constructionCurrency?: string;\n exchangeRateOne?: number;\n // Comisión de agencia: vistos solo en Revalidate Itinerary.\n commissionPercentage?: number;\n commissionAmount?: number;\n cat35CommissionPercentage?: number;\n cat35CommissionAmount?: number;\n cat35MarkupAmount?: number;\n commissionAmountInEquivalent?: number;\n commissionSource?: string;\n}\n\nexport interface TotalFare {\n totalPrice: number;\n totalTaxAmount?: number;\n currency: string;\n baseFareAmount?: number;\n baseFareCurrency?: string;\n constructionAmount?: number;\n constructionCurrency?: string;\n equivalentAmount?: number;\n equivalentCurrency?: string;\n}\n\n/** Disponibilidad del segmento dentro de un componente de tarifa. */\nexport interface FareComponentSegmentDetail {\n bookingCode?: string;\n cabinCode?: string;\n mealCode?: string;\n seatsAvailable?: number;\n availabilityBreak?: boolean;\n fareBreakPoint?: boolean;\n}\n\nexport interface FareMessage {\n type: string;\n code: string;\n /** Visto en sandbox de Revalidate. */\n carrier?: string;\n info: string;\n}\n\n// ---------------------------------------------------------------------------\n// Respuesta tal cual la manda Sabre (con `ref`). Interna: el SDK expone la desnormalizada.\n// ---------------------------------------------------------------------------\n\nexport interface RawFareComponent extends Ref {\n beginAirport?: string;\n endAirport?: string;\n segments?: Array<{ segment: FareComponentSegmentDetail }>;\n}\n\nexport interface RawBaggageInformation {\n provisionType?: string;\n airlineCode?: string;\n /** Índices de segmento, no referencias a descriptores. */\n segments?: Array<{ id: number }>;\n allowance?: Ref;\n}\n\nexport interface RawPassengerInfo {\n passengerType: string;\n passengerNumber?: number;\n nonRefundable?: boolean;\n fareComponents?: RawFareComponent[];\n taxes?: Ref[];\n taxSummaries?: Ref[];\n obFees?: Ref[];\n currencyConversion?: CurrencyConversion;\n passengerTotalFare?: PassengerTotalFare;\n baggageInformation?: RawBaggageInformation[];\n // Vistos solo en Revalidate Itinerary.\n fareMessages?: FareMessage[];\n fareCalcLine?: { info: string };\n}\n\nexport interface RawFare {\n mandatoryInd?: boolean;\n validatingCarrierCode?: string;\n vita?: boolean;\n eTicketable?: boolean;\n lastTicketDate?: string;\n lastTicketTime?: string;\n governingCarriers?: string;\n passengerInfoList: Array<{ passengerInfo: RawPassengerInfo }>;\n totalFare?: TotalFare;\n validatingCarriers?: Ref[];\n}\n\nexport interface RawPricingInformation {\n pricingSubsource?: string;\n /** P. ej. `ATPCO`. Visto en Revalidate y en sandbox de BFM. */\n distributionModel?: string;\n fare: RawFare;\n}\n\nexport interface RawItinerary {\n id: number;\n pricingSource?: string;\n /** Visto solo en Revalidate Itinerary. */\n currentItinerary?: boolean;\n /** Visto en sandbox de BFM; significado sin confirmar. */\n diversitySwapper?: { weighedPrice?: number };\n legs: Ref[];\n pricingInformation: RawPricingInformation[];\n}\n\nexport interface RawItineraryGroup {\n groupDescription: { legDescriptions: LegDescription[] };\n itineraries: RawItinerary[];\n}\n\n/** Contenido de `groupedItineraryResponse` tal cual llega de Sabre. */\nexport interface RawGroupedItineraryResponse {\n version: string;\n messages?: ItineraryMessage[];\n statistics?: { itineraryCount: number };\n scheduleDescs?: ScheduleDesc[];\n taxDescs?: TaxDesc[];\n taxSummaryDescs?: TaxSummaryDesc[];\n obFeeDescs?: ObFeeDesc[];\n fareComponentDescs?: FareComponentDesc[];\n validatingCarrierDescs?: ValidatingCarrierDesc[];\n baggageAllowanceDescs?: BaggageAllowanceDesc[];\n legDescs?: LegDesc[];\n itineraryGroups?: RawItineraryGroup[];\n}\n\n// ---------------------------------------------------------------------------\n// Respuesta desnormalizada (superficie pública)\n// ---------------------------------------------------------------------------\n\n/** Tramo con sus schedules resueltos. */\nexport interface Leg extends Omit<LegDesc, 'schedules'> {\n schedules: LegSchedule[];\n}\n\n/** Schedule resuelto, con lo que la referencia del tramo agrega. */\nexport type LegSchedule = ScheduleDesc & Omit<LegScheduleRef, 'ref'>;\n\n/** Segmento de un componente de tarifa: lo del descriptor más la disponibilidad del itinerario. */\nexport interface FareComponentSegment {\n segment: FareComponentDescSegment['segment'] & FareComponentSegmentDetail;\n}\n\n/** Componente de tarifa resuelto: descriptor + datos propios del itinerario. */\nexport interface FareComponent extends Omit<FareComponentDesc, 'segments'> {\n beginAirport?: string;\n endAirport?: string;\n segments?: FareComponentSegment[];\n}\n\nexport interface BaggageInformation extends Omit<RawBaggageInformation, 'allowance'> {\n allowance?: BaggageAllowanceDesc;\n}\n\nexport interface PassengerInfo\n extends Omit<RawPassengerInfo, 'fareComponents' | 'taxes' | 'taxSummaries' | 'obFees' | 'baggageInformation'> {\n fareComponents?: FareComponent[];\n taxes?: TaxDesc[];\n taxSummaries?: TaxSummaryDesc[];\n obFees?: ObFeeDesc[];\n baggageInformation?: BaggageInformation[];\n}\n\nexport interface Fare extends Omit<RawFare, 'passengerInfoList' | 'validatingCarriers'> {\n passengerInfoList: Array<{ passengerInfo: PassengerInfo }>;\n validatingCarriers?: ValidatingCarrierDesc[];\n}\n\nexport interface PricingInformation extends Omit<RawPricingInformation, 'fare'> {\n fare: Fare;\n}\n\nexport interface Itinerary extends Omit<RawItinerary, 'legs' | 'pricingInformation'> {\n legs: Leg[];\n pricingInformation: PricingInformation[];\n}\n\nexport interface ItineraryGroup {\n groupDescription: { legDescriptions: LegDescription[] };\n itineraries: Itinerary[];\n}\n\n/**\n * `groupedItineraryResponse` con cada `ref` resuelto al objeto completo. Los arrays de\n * descriptores (`scheduleDescs`, `legDescs`, …) ya no se exponen: su contenido vive\n * dentro de cada itinerario.\n */\nexport interface GroupedItineraryResponse {\n version: string;\n messages: ItineraryMessage[];\n statistics?: { itineraryCount: number };\n itineraryGroups: ItineraryGroup[];\n}\n\n// ---------------------------------------------------------------------------\n// Desnormalizador\n// ---------------------------------------------------------------------------\n\n/**\n * Resuelve cada `{ ref, ...resto }` a `{ ...descriptor, ...resto }` (sin `ref`; el `id` del\n * descriptor se conserva). En los componentes de tarifa, `segments` se fusiona elemento a\n * elemento: el descriptor aporta `stopover` y el itinerario la disponibilidad; si los dos\n * traen `segments` con distinto largo, la respuesta es malformada.\n *\n * Un `ref` sin descriptor con ese `id` es una respuesta malformada: lanza `SabreError`\n * no reintentable en vez de devolver un objeto a medias. No muta la entrada.\n */\nexport function denormalizeGroupedItineraryResponse(\n raw: RawGroupedItineraryResponse,\n service: string,\n): GroupedItineraryResponse {\n const resolver = new Resolver(raw, service);\n return {\n version: raw.version,\n messages: raw.messages ?? [],\n ...(raw.statistics === undefined ? {} : { statistics: raw.statistics }),\n itineraryGroups: (raw.itineraryGroups ?? []).map((group) => ({\n groupDescription: group.groupDescription,\n itineraries: group.itineraries.map((itinerary) => resolver.itinerary(itinerary)),\n })),\n };\n}\n\nclass Resolver {\n readonly #service: string;\n readonly #schedules: Map<number, ScheduleDesc>;\n readonly #legs: Map<number, LegDesc>;\n readonly #taxes: Map<number, TaxDesc>;\n readonly #taxSummaries: Map<number, TaxSummaryDesc>;\n readonly #obFees: Map<number, ObFeeDesc>;\n readonly #fareComponents: Map<number, FareComponentDesc>;\n readonly #validatingCarriers: Map<number, ValidatingCarrierDesc>;\n readonly #baggageAllowances: Map<number, BaggageAllowanceDesc>;\n\n constructor(raw: RawGroupedItineraryResponse, service: string) {\n this.#service = service;\n this.#schedules = byId(raw.scheduleDescs);\n this.#legs = byId(raw.legDescs);\n this.#taxes = byId(raw.taxDescs);\n this.#taxSummaries = byId(raw.taxSummaryDescs);\n this.#obFees = byId(raw.obFeeDescs);\n this.#fareComponents = byId(raw.fareComponentDescs);\n this.#validatingCarriers = byId(raw.validatingCarrierDescs);\n this.#baggageAllowances = byId(raw.baggageAllowanceDescs);\n }\n\n itinerary(itinerary: RawItinerary): Itinerary {\n return {\n ...itinerary,\n legs: itinerary.legs.map((ref) => this.#leg(ref)),\n pricingInformation: itinerary.pricingInformation.map((pricing) => ({\n ...pricing,\n fare: this.#fare(pricing.fare),\n })),\n };\n }\n\n #leg(ref: Ref): Leg {\n const leg = this.#merge(this.#legs, 'legDescs', ref);\n return { ...leg, schedules: leg.schedules.map((schedule) => this.#merge(this.#schedules, 'scheduleDescs', schedule)) };\n }\n\n #fare(fare: RawFare): Fare {\n const { validatingCarriers, ...rest } = fare;\n return {\n ...rest,\n passengerInfoList: fare.passengerInfoList.map(({ passengerInfo, ...entry }) => ({\n ...entry,\n passengerInfo: this.#passengerInfo(passengerInfo),\n })),\n ...(validatingCarriers === undefined\n ? {}\n : {\n validatingCarriers: validatingCarriers.map((ref) =>\n this.#merge(this.#validatingCarriers, 'validatingCarrierDescs', ref),\n ),\n }),\n };\n }\n\n #passengerInfo(info: RawPassengerInfo): PassengerInfo {\n const { fareComponents, taxes, taxSummaries, obFees, baggageInformation, ...rest } = info;\n const result: PassengerInfo = { ...rest };\n if (fareComponents !== undefined) result.fareComponents = fareComponents.map((ref) => this.#fareComponent(ref));\n if (taxes !== undefined) result.taxes = taxes.map((ref) => this.#merge(this.#taxes, 'taxDescs', ref));\n if (taxSummaries !== undefined) {\n result.taxSummaries = taxSummaries.map((ref) => this.#merge(this.#taxSummaries, 'taxSummaryDescs', ref));\n }\n if (obFees !== undefined) result.obFees = obFees.map((ref) => this.#merge(this.#obFees, 'obFeeDescs', ref));\n if (baggageInformation !== undefined) {\n result.baggageInformation = baggageInformation.map(({ allowance, ...bag }) => ({\n ...bag,\n ...(allowance === undefined\n ? {}\n : { allowance: this.#merge(this.#baggageAllowances, 'baggageAllowanceDescs', allowance) }),\n }));\n }\n return result;\n }\n\n #fareComponent(ref: RawFareComponent): FareComponent {\n const desc = this.#lookup(this.#fareComponents, 'fareComponentDescs', ref.ref);\n const { ref: _ref, segments: siteSegments, ...site } = ref;\n const { segments: descSegments, ...descRest } = desc;\n if (descSegments !== undefined && siteSegments !== undefined && descSegments.length !== siteSegments.length) {\n throw this.#malformed(\n `fareComponents con ${siteSegments.length} segmentos y fareComponentDescs ${ref.ref} con ${descSegments.length}`,\n );\n }\n const segments = mergeSegments(descSegments, siteSegments);\n return { ...descRest, ...site, ...(segments === undefined ? {} : { segments }) };\n }\n\n /** `{ ref, ...resto }` → `{ ...descriptor, ...resto }`. */\n #merge<T extends { id: number }>(index: Map<number, T>, kind: string, ref: Ref): T {\n const { ref: id, ...site } = ref;\n return { ...this.#lookup(index, kind, id), ...site };\n }\n\n #lookup<T>(index: Map<number, T>, kind: string, id: number): T {\n const desc = index.get(id);\n if (desc === undefined) throw this.#malformed(`ref ${id} sin descriptor en ${kind}`);\n return desc;\n }\n\n #malformed(detail: string): SabreError {\n return new SabreError(`${this.#service}: respuesta malformada, ${detail}`, { retryable: false });\n }\n}\n\nfunction byId<T extends { id: number }>(descs: T[] | undefined): Map<number, T> {\n return new Map((descs ?? []).map((desc) => [desc.id, desc]));\n}\n\nfunction mergeSegments(\n desc: FareComponentDescSegment[] | undefined,\n site: Array<{ segment: FareComponentSegmentDetail }> | undefined,\n): FareComponentSegment[] | undefined {\n if (desc === undefined && site === undefined) return undefined;\n // Los largos ya se validaron iguales cuando vienen los dos.\n const length = desc?.length ?? site?.length ?? 0;\n return Array.from({ length }, (_, i) => ({\n segment: { ...desc?.[i]?.segment, ...site?.[i]?.segment },\n }));\n}\n","// Clasificación de errores de negocio en `groupedItineraryResponse.messages[]`, compartida por\n// los servicios que responden con ese modelo (Bargain Finder Max, Revalidate Itinerary).\n// Ver sabre-wiki/wiki/sdk/manejo-y-mapeo-de-errores.md.\nimport { SabreBusinessError, SabreError } from '../errors/index.js';\nimport type { ItineraryMessage } from './grouped-itinerary.js';\n\n/** Entrada de catálogo: se compara por substring del `text`, sin distinguir mayúsculas. */\nexport interface ItineraryMessageCatalogEntry {\n code: string;\n retryable: boolean;\n}\n\n/**\n * Paso 3 del orden de detección: un mensaje con `severity: Error` en\n * `groupedItineraryResponse.messages[]` (respuesta 200) es un `SabreBusinessError`.\n *\n * En sandbox, los mensajes `Error` son genéricos (`No complete journey can be built…`,\n * `Error during Processing`) y el texto del catálogo llega en un mensaje `Info`\n * (`NO FLIGHT SCHEDULES FOR QUALIFIERS USED`). Por eso, cuando hay algún `Error`, el\n * catálogo se busca en el `text` de todos los mensajes.\n */\nexport function classifyItineraryMessages(\n body: unknown,\n service: string,\n catalog: ReadonlyArray<ItineraryMessageCatalogEntry>,\n): SabreError | undefined {\n const response = isObject(body) ? body.groupedItineraryResponse : undefined;\n if (!isObject(response)) {\n return new SabreError(`${service}: respuesta malformada, falta groupedItineraryResponse`, {\n retryable: false,\n raw: body,\n });\n }\n const messages = Array.isArray(response.messages) ? (response.messages as Partial<ItineraryMessage>[]) : [];\n const error = messages.find((message) => message.severity?.toLowerCase() === 'error');\n if (error === undefined) return undefined;\n\n const match = findInCatalog(messages, catalog);\n const text = match?.text ?? (typeof error.text === 'string' ? error.text : '');\n const known = match?.entry;\n const code = known?.code ?? error.code ?? text;\n return new SabreBusinessError(`${service}: ${text || code}`, {\n service,\n code,\n retryable: known?.retryable ?? false,\n raw: body,\n });\n}\n\nfunction findInCatalog(\n messages: Partial<ItineraryMessage>[],\n catalog: ReadonlyArray<ItineraryMessageCatalogEntry>,\n): { entry: ItineraryMessageCatalogEntry; text: string } | undefined {\n for (const message of messages) {\n if (typeof message.text !== 'string') continue;\n const text = message.text.toLowerCase();\n const entry = catalog.find((candidate) => text.includes(candidate.code.toLowerCase()));\n if (entry !== undefined) return { entry, text: message.text };\n }\n return undefined;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","// Bargain Finder Max v5 (`POST /v5/offers/shop`).\n// Ver sabre-wiki/wiki/entities/bargain-finder-max.md.\nimport type { SabreError } from '../errors/index.js';\nimport type { RestTransport } from '../http/rest-transport.js';\nimport type { RetryOptions } from '../http/retry.js';\nimport {\n denormalizeGroupedItineraryResponse,\n type GroupedItineraryResponse,\n type RawGroupedItineraryResponse,\n} from './grouped-itinerary.js';\nimport { classifyItineraryMessages, type ItineraryMessageCatalogEntry } from './itinerary-messages.js';\nimport type { OtaAirLowFareSearchRq } from './low-fare-search-request.js';\n\nexport const BARGAIN_FINDER_MAX_SERVICE = 'bargainFinderMax';\nconst PATH = '/v5/offers/shop';\n\n/** Body de Bargain Finder Max v5, tal cual lo documenta Sabre. */\nexport interface BargainFinderMaxRequest {\n OTA_AirLowFareSearchRQ: OtaAirLowFareSearchRq;\n}\n\n/** `groupedItineraryResponse` con las referencias ya resueltas. */\nexport type BargainFinderMaxResponse = GroupedItineraryResponse;\n\nexport interface RequestOptions {\n signal?: AbortSignal;\n /** Pisa los reintentos del cliente solo para esta request. */\n retry?: Partial<RetryOptions>;\n}\n\n/**\n * Catálogo de errores de BFM (guía oficial de errores). Se compara por substring del\n * `text` porque Sabre agrega detalle variable. Los temporales son reintentables: BFM es\n * una lectura idempotente y Sabre indica reintentar.\n */\nexport const BARGAIN_FINDER_MAX_CATALOG: ReadonlyArray<ItineraryMessageCatalogEntry> = [\n { code: 'No Availability', retryable: false },\n { code: 'NO FLIGHT SCHEDULES FOR QUALIFIERS USED', retryable: false },\n { code: 'Connection reset by peer', retryable: true },\n { code: 'Transmission timeout', retryable: true },\n { code: 'Insufficient resources', retryable: true },\n { code: 'MAX NBR COMBINATIONS EXCEEDED', retryable: true },\n];\n\nexport async function bargainFinderMax(\n transport: RestTransport,\n request: BargainFinderMaxRequest,\n options: RequestOptions = {},\n): Promise<BargainFinderMaxResponse> {\n if (typeof request !== 'object' || request === null || typeof request.OTA_AirLowFareSearchRQ !== 'object') {\n throw new TypeError('sabre-client: bargainFinderMax espera { OTA_AirLowFareSearchRQ: { ... } }');\n }\n const body = await transport.request<{ groupedItineraryResponse: RawGroupedItineraryResponse }>({\n method: 'POST',\n path: PATH,\n service: BARGAIN_FINDER_MAX_SERVICE,\n // POST, pero de solo lectura: se puede reintentar sin efectos duplicados.\n idempotent: true,\n body: request,\n classify: classifyBargainFinderMax,\n ...(options.retry === undefined ? {} : { retry: options.retry }),\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n });\n return denormalizeGroupedItineraryResponse(body.groupedItineraryResponse, BARGAIN_FINDER_MAX_SERVICE);\n}\n\n/** Ver `classifyItineraryMessages`. */\nexport function classifyBargainFinderMax(body: unknown): SabreError | undefined {\n return classifyItineraryMessages(body, BARGAIN_FINDER_MAX_SERVICE, BARGAIN_FINDER_MAX_CATALOG);\n}\n","// Reglas para fijar los vuelos de un itinerario desnormalizado, compartidas por los\n// helpers que arman requests a partir de él (Revalidate Itinerary, Create Booking).\n// Ver sabre-wiki/wiki/concepts/modelo-de-itinerario.md.\nimport type { Itinerary, ItineraryGroup, LegSchedule } from './grouped-itinerary.js';\n\n/** Un vuelo del itinerario con su fecha de salida ya resuelta y su clase de servicio. */\nexport interface ItineraryFlight {\n /** Índice del tramo (`legs[]`) al que pertenece. */\n legIndex: number;\n schedule: LegSchedule;\n /** `YYYY-MM-DD`, hora local del aeropuerto de salida. */\n departureDate: string;\n /** `YYYY-MM-DD`, hora local del aeropuerto de llegada. */\n arrivalDate: string;\n bookingCode: string;\n}\n\n/**\n * Aplana los vuelos del itinerario en orden.\n *\n * - La clase de servicio de cada vuelo sale de `fareComponents[].segments[].bookingCode` del\n * primer pasajero de la primera cotización, en el orden de los vuelos del itinerario.\n * - Las fechas salen de `legDescriptions[].departureDate` más `departureDateAdjustment` del\n * schedule (salida) y `arrival.dateAdjustment` (llegada).\n */\nexport function itineraryFlights(group: ItineraryGroup, itinerary: Itinerary): ItineraryFlight[] {\n const { legDescriptions } = group.groupDescription;\n if (legDescriptions.length !== itinerary.legs.length) {\n throw new TypeError(\n `sabre-client: el itinerario tiene ${itinerary.legs.length} tramos y el grupo ${legDescriptions.length}`,\n );\n }\n const classes = bookingCodes(itinerary);\n const flightCount = itinerary.legs.reduce((n, leg) => n + leg.schedules.length, 0);\n if (classes.length !== flightCount) {\n throw new TypeError(\n `sabre-client: el itinerario tiene ${flightCount} vuelos y ${classes.length} clases de servicio en fareComponents`,\n );\n }\n\n let next = 0;\n return itinerary.legs.flatMap((leg, legIndex) => {\n const legDate = legDescriptions[legIndex]!.departureDate;\n return leg.schedules.map((schedule) => {\n const departureDate = addDays(legDate, schedule.departureDateAdjustment ?? 0);\n return {\n legIndex,\n schedule,\n departureDate,\n arrivalDate: addDays(departureDate, schedule.arrival.dateAdjustment ?? 0),\n bookingCode: classes[next++]!,\n };\n });\n });\n}\n\nfunction bookingCodes(itinerary: Itinerary): string[] {\n const passenger = itinerary.pricingInformation[0]?.fare.passengerInfoList[0]?.passengerInfo;\n return (passenger?.fareComponents ?? []).flatMap((component) =>\n (component.segments ?? []).map(({ segment }) => {\n if (segment.bookingCode === undefined) {\n throw new TypeError('sabre-client: un segmento de fareComponents no trae bookingCode');\n }\n return segment.bookingCode;\n }),\n );\n}\n\n/** `2026-09-11` + n días, en calendario puro (sin zona horaria). */\nfunction addDays(date: string, days: number): string {\n if (days === 0) return date;\n const [year, month, day] = date.split('-').map(Number) as [number, number, number];\n return new Date(Date.UTC(year, month - 1, day + days)).toISOString().slice(0, 10);\n}\n","// Revalidate Itinerary v5 (`POST /v5/shop/flights/revalidate`).\n// Ver sabre-wiki/wiki/entities/revalidate-itinerary.md.\nimport type { SabreError } from '../errors/index.js';\nimport type { RestTransport } from '../http/rest-transport.js';\nimport { BARGAIN_FINDER_MAX_CATALOG, type BargainFinderMaxRequest, type RequestOptions } from './bargain-finder-max.js';\nimport {\n denormalizeGroupedItineraryResponse,\n type GroupedItineraryResponse,\n type Itinerary,\n type ItineraryGroup,\n type RawGroupedItineraryResponse,\n} from './grouped-itinerary.js';\nimport { type ItineraryFlight, itineraryFlights } from './itinerary-flights.js';\nimport { classifyItineraryMessages, type ItineraryMessageCatalogEntry } from './itinerary-messages.js';\nimport type {\n LowFareSearchFlight,\n LowFareSearchOriginDestination,\n OtaAirLowFareSearchRq,\n} from './low-fare-search-request.js';\n\nexport const REVALIDATE_ITINERARY_SERVICE = 'revalidateItinerary';\nconst PATH = '/v5/shop/flights/revalidate';\n\n/** Body de Revalidate Itinerary v5: el mismo `OTA_AirLowFareSearchRQ` que BFM, con los vuelos fijados. */\nexport interface RevalidateItineraryRequest {\n OTA_AirLowFareSearchRQ: OtaAirLowFareSearchRq;\n}\n\n/** `groupedItineraryResponse` con las referencias ya resueltas. */\nexport type RevalidateItineraryResponse = GroupedItineraryResponse;\n\nexport async function revalidateItinerary(\n transport: RestTransport,\n request: RevalidateItineraryRequest,\n options: RequestOptions = {},\n): Promise<RevalidateItineraryResponse> {\n if (typeof request !== 'object' || request === null || typeof request.OTA_AirLowFareSearchRQ !== 'object') {\n throw new TypeError('sabre-client: revalidateItinerary espera { OTA_AirLowFareSearchRQ: { ... } }');\n }\n const body = await transport.request<{ groupedItineraryResponse: RawGroupedItineraryResponse }>({\n method: 'POST',\n path: PATH,\n service: REVALIDATE_ITINERARY_SERVICE,\n // POST, pero de solo lectura: no sostiene inventario, se puede reintentar.\n idempotent: true,\n body: request,\n classify: classifyRevalidateItinerary,\n ...(options.retry === undefined ? {} : { retry: options.retry }),\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n });\n return denormalizeGroupedItineraryResponse(body.groupedItineraryResponse, REVALIDATE_ITINERARY_SERVICE);\n}\n\n/**\n * Catálogo de errores de Revalidate (guía oficial de errores de Revalidate Itinerary, en la\n * documentación SOAP de BFM 7.2.0; ver sabre-wiki/wiki/entities/revalidate-itinerary.md).\n * Las cinco condiciones describen un dato que no existe (tarifa, horario o disponibilidad):\n * reintentar no cambia el resultado. En producción, `NO FARE FOR CLASS USED` llegó con\n * `code: 'PROCESS'`; el catálogo le da un `code` estable.\n *\n * Los temporales se heredan de BFM (mismo motor), con `retryable: true`.\n */\nexport const REVALIDATE_ITINERARY_CATALOG: ReadonlyArray<ItineraryMessageCatalogEntry> = [\n { code: 'NO COMBINABLE FARES FOR CLASS USED', retryable: false },\n { code: 'NO FARE FOR CLASS USED', retryable: false },\n { code: 'NO FLIGHT SCHEDULES FOR QUALIFIERS USED', retryable: false },\n { code: 'NO SUCH FLIGHT', retryable: false },\n { code: 'NO AVAILABILITY', retryable: false },\n ...BARGAIN_FINDER_MAX_CATALOG.filter((entry) => entry.retryable),\n];\n\n/** Ver `classifyItineraryMessages`. */\nexport function classifyRevalidateItinerary(body: unknown): SabreError | undefined {\n return classifyItineraryMessages(body, REVALIDATE_ITINERARY_SERVICE, REVALIDATE_ITINERARY_CATALOG);\n}\n\nexport interface RevalidateItineraryRequestSource {\n /** Request de BFM que produjo el itinerario: aporta `Version`, `POS`, pasajeros y `TPA_Extensions`. */\n search: BargainFinderMaxRequest;\n /** Grupo del itinerario: aporta la fecha de cada tramo. */\n group: ItineraryGroup;\n itinerary: Itinerary;\n}\n\n/**\n * Arma el request de Revalidate Itinerary para un itinerario devuelto por BFM, fijando cada\n * vuelo en `OriginDestinationInformation[].TPA_Extensions.Flight[]`.\n *\n * - Clases de servicio y fechas: ver `itineraryFlights`. Las horas salen de `time` sin el offset.\n * - `MaxStopsQuantity` es el máximo de conexiones de un tramo, para no rechazar itinerarios\n * con escala.\n * - `Fixed: false` y `VerificationItinCallLogic: \"L\"` se copian del ejemplo de Sabre; su\n * efecto no está documentado.\n */\nexport function buildRevalidateItineraryRequest(source: RevalidateItineraryRequestSource): RevalidateItineraryRequest {\n const { search, group, itinerary } = source;\n const flights = itineraryFlights(group, itinerary);\n\n const originDestinations = itinerary.legs.map((_leg, i): LowFareSearchOriginDestination => {\n const legFlights = flights.filter((f) => f.legIndex === i).map(flight);\n const first = legFlights[0]!;\n const last = legFlights.at(-1)!;\n return {\n Fixed: false,\n DepartureDateTime: first.DepartureDateTime,\n OriginLocation: { LocationCode: first.OriginLocation.LocationCode },\n DestinationLocation: { LocationCode: last.DestinationLocation.LocationCode },\n TPA_Extensions: { Flight: legFlights },\n };\n });\n\n const { Version, POS, TravelerInfoSummary, TPA_Extensions } = search.OTA_AirLowFareSearchRQ;\n return {\n OTA_AirLowFareSearchRQ: {\n Version,\n POS,\n OriginDestinationInformation: originDestinations,\n TravelPreferences: {\n MaxStopsQuantity: Math.max(...itinerary.legs.map((leg) => leg.schedules.length - 1)),\n TPA_Extensions: { VerificationItinCallLogic: { Value: 'L' } },\n },\n TravelerInfoSummary,\n ...(TPA_Extensions === undefined ? {} : { TPA_Extensions }),\n },\n };\n}\n\nfunction flight({ schedule, departureDate, arrivalDate, bookingCode }: ItineraryFlight): LowFareSearchFlight {\n const { carrier } = schedule;\n return {\n Type: 'A',\n Number: carrier.marketingFlightNumber,\n DepartureDateTime: `${departureDate}T${localTime(schedule.departure.time)}`,\n ArrivalDateTime: `${arrivalDate}T${localTime(schedule.arrival.time)}`,\n ClassOfService: bookingCode,\n OriginLocation: { LocationCode: schedule.departure.airport },\n DestinationLocation: { LocationCode: schedule.arrival.airport },\n Airline: {\n Marketing: carrier.marketing,\n ...(carrier.operating === undefined ? {} : { Operating: carrier.operating }),\n },\n };\n}\n\n/** `17:10:00+02:00` → `17:10:00`. */\nfunction localTime(time: string): string {\n return time.slice(0, 8);\n}\n","// Módulo de dominio `sabre.air`. Ver sabre-wiki/wiki/sdk/convenciones-de-nombres-y-versionado.md.\nimport type { RestTransport } from '../http/rest-transport.js';\nimport {\n bargainFinderMax,\n type BargainFinderMaxRequest,\n type BargainFinderMaxResponse,\n type RequestOptions,\n} from './bargain-finder-max.js';\nimport {\n revalidateItinerary,\n type RevalidateItineraryRequest,\n type RevalidateItineraryResponse,\n} from './revalidate-itinerary.js';\n\nexport class Air {\n readonly #transport: RestTransport;\n\n /** @internal Lo construye el cliente `Sabre`. */\n constructor(transport: RestTransport) {\n this.#transport = transport;\n }\n\n /**\n * Bargain Finder Max v5: busca itinerarios de menor precio. Devuelve el\n * `groupedItineraryResponse` con las referencias ya resueltas.\n */\n bargainFinderMax(request: BargainFinderMaxRequest, options?: RequestOptions): Promise<BargainFinderMaxResponse> {\n return bargainFinderMax(this.#transport, request, options);\n }\n\n /**\n * Revalidate Itinerary v5: revalida disponibilidad y precio de un itinerario ya elegido,\n * sin sostener inventario. El request se arma con `buildRevalidateItineraryRequest`.\n */\n revalidateItinerary(\n request: RevalidateItineraryRequest,\n options?: RequestOptions,\n ): Promise<RevalidateItineraryResponse> {\n return revalidateItinerary(this.#transport, request, options);\n }\n}\n","// Redacción obligatoria antes de que cualquier dato llegue al logger.\n// Ver sabre-wiki/wiki/sdk/configuracion-logging-y-build.md.\n\nexport const REDACTED = '[REDACTED]';\n\n/**\n * Claves cuyo valor se enmascara completo, comparadas sin distinguir mayúsculas\n * ni separadores (`client_secret`, `Client-Secret` y `clientSecret` son la misma).\n */\nconst SENSITIVE_KEYS = new Set(\n [\n // Credenciales\n 'clientSecret',\n 'password',\n 'username',\n 'authorization',\n 'binarySecurityToken',\n 'accessToken',\n 'refreshToken',\n 'token',\n // Datos de pasajero\n 'travelers',\n 'passengers',\n ].map(normalizeKey),\n);\n\nfunction normalizeKey(key: string): string {\n return key.replace(/[-_\\s]/g, '').toLowerCase();\n}\n\nexport function isSensitiveKey(key: string): boolean {\n return SENSITIVE_KEYS.has(normalizeKey(key));\n}\n\n/** Copia profunda de `value` con los campos sensibles enmascarados. No muta la entrada. */\nexport function redact(value: unknown): unknown {\n return redactValue(value, new WeakSet());\n}\n\nfunction redactValue(value: unknown, seen: WeakSet<object>): unknown {\n if (value === null || typeof value !== 'object') return value;\n if (seen.has(value)) return '[Circular]';\n seen.add(value);\n\n if (Array.isArray(value)) return value.map((item) => redactValue(item, seen));\n if (value instanceof Headers) return redactEntries(value.entries(), seen);\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Error) {\n // Los errores del SDK definen toJSON sin `raw`; para el resto, solo nombre y mensaje.\n const json = 'toJSON' in value && typeof value.toJSON === 'function' ? value.toJSON() : undefined;\n return redactValue(json ?? { name: value.name, message: value.message }, seen);\n }\n return redactEntries(Object.entries(value), seen);\n}\n\nfunction redactEntries(entries: Iterable<[string, unknown]>, seen: WeakSet<object>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, item] of entries) {\n out[key] = isSensitiveKey(key) ? REDACTED : redactValue(item, seen);\n }\n return out;\n}\n","// Logger inyectable. Ver sabre-wiki/wiki/sdk/configuracion-logging-y-build.md.\nimport { redact } from './redact.js';\n\n/**\n * Interfaz mínima de logger, compatible con `winston` y `console`.\n * Con `pino`, que invierte el orden: `info: (m, c) => pino.info(c, m)`.\n */\nexport interface SabreLogger {\n debug(message: string, context?: Record<string, unknown>): void;\n info(message: string, context?: Record<string, unknown>): void;\n warn(message: string, context?: Record<string, unknown>): void;\n error(message: string, context?: Record<string, unknown>): void;\n}\n\nexport type SabreLogLevel = keyof SabreLogger;\n\n/** Eventos estables que emite el SDK como `message`. */\nexport type SabreLogEvent =\n | 'sabre.request.start'\n | 'sabre.request.end'\n | 'sabre.request.retry'\n | 'sabre.auth.token.refresh'\n | 'sabre.auth.token.store';\n\n/** Logger interno: redacta siempre el contexto y no hace nada si no hay logger. */\nexport class EventLogger {\n readonly #logger: SabreLogger | undefined;\n\n constructor(logger?: SabreLogger) {\n this.#logger = logger;\n }\n\n emit(level: SabreLogLevel, event: SabreLogEvent, context: Record<string, unknown> = {}): void {\n if (this.#logger === undefined) return;\n try {\n this.#logger[level](event, redact(context) as Record<string, unknown>);\n } catch {\n // Un logger que falla no debe romper la request en curso.\n }\n }\n}\n","// Armado de la request de OAuth Token Create, una estrategia por versión.\n// Ver sabre-wiki/wiki/entities/oauth-token-create.md: v2 y v3 no son intercambiables.\nimport type { SabreAuthVersion, SabreCredentials, SabreCredentialsV2 } from '../config.js';\n\nexport interface TokenRequest {\n path: string;\n /** Valor del header `Authorization` (`Basic ...`). */\n authorization: string;\n body: URLSearchParams;\n}\n\n/** v3: `Basic base64(clientId:clientSecret)` y el EPR en el body con `grant_type=password`. */\nexport function buildTokenRequestV3(credentials: SabreCredentials): TokenRequest {\n return {\n path: '/v3/auth/token',\n authorization: `Basic ${base64(`${credentials.clientId}:${credentials.clientSecret}`)}`,\n body: new URLSearchParams({\n grant_type: 'password',\n username: credentials.username,\n password: credentials.password,\n }),\n };\n}\n\n/** v2: doble Base64 sobre el EPR y su password, con `grant_type=client_credentials`. */\nexport function buildTokenRequestV2(credentials: SabreCredentialsV2): TokenRequest {\n return {\n path: '/v2/auth/token',\n authorization: `Basic ${base64(`${base64(credentials.username)}:${base64(credentials.password)}`)}`,\n body: new URLSearchParams({ grant_type: 'client_credentials' }),\n };\n}\n\nexport function buildTokenRequest(\n authVersion: SabreAuthVersion,\n credentials: SabreCredentials | SabreCredentialsV2,\n): TokenRequest {\n // `resolveConfig` ya exige clientId/clientSecret cuando la versión es v3.\n return authVersion === 'v3'\n ? buildTokenRequestV3(credentials as SabreCredentials)\n : buildTokenRequestV2(credentials);\n}\n\n/** Base64 de los bytes UTF-8 de `text`, solo con Web APIs (sin `Buffer`). */\nexport function base64(text: string): string {\n let binary = '';\n for (const byte of new TextEncoder().encode(text)) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n","// Almacén de token inyectable por el consumidor. Ver sabre-wiki/wiki/sdk/renovacion-token-oauth.md,\n// sección \"Decisiones de la Fase 4\" (decisión B).\nimport type { SabreAuthVersion, SabreCredentials, SabreCredentialsV2, SabreEnvironment } from '../config.js';\n\n/** Token ATK tal cual se guarda: tiempos absolutos, para que otro proceso sepa cuánto le queda. */\nexport interface StoredToken {\n accessToken: string;\n /** Momento de obtención, en ms desde epoch. */\n obtainedAt: number;\n /** Momento de expiración, en ms desde epoch. */\n expiresAt: number;\n}\n\n/**\n * Almacén de token del consumidor (archivo, Redis, KV…). El SDK no trae implementaciones.\n *\n * `key` identifica la configuración (entorno, versión de OAuth y credencial, sin secretos):\n * un mismo store puede servir a varios clientes sin mezclar sus tokens. El token es un\n * secreto: protegerlo dentro del store es responsabilidad del consumidor.\n *\n * Si `get` o `set` lanzan, el SDK sigue con su caché en memoria: el store nunca rompe una llamada.\n */\nexport interface SabreTokenStore {\n get(key: string): Promise<StoredToken | undefined>;\n set(key: string, token: StoredToken): Promise<void>;\n}\n\n/**\n * `sabre-client:<environment>:<authVersion>:<hash>`, donde `hash` son los primeros 16 bytes\n * en hex del SHA-256 del username EPR (y del clientId en v3). No contiene secretos.\n */\nexport async function tokenStoreKey(\n environment: SabreEnvironment,\n authVersion: SabreAuthVersion,\n credentials: Readonly<SabreCredentials | SabreCredentialsV2>,\n): Promise<string> {\n const identity = authVersion === 'v3' ? `${credentials.clientId}\\n${credentials.username}` : credentials.username;\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(identity));\n const hash = [...new Uint8Array(digest).slice(0, 16)].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n return `sabre-client:${environment}:${authVersion}:${hash}`;\n}\n\n/** Un valor de `get` que no tenga la forma de `StoredToken` se ignora. */\nexport function isStoredToken(value: unknown): value is StoredToken {\n if (typeof value !== 'object' || value === null) return false;\n const { accessToken, obtainedAt, expiresAt } = value as Record<string, unknown>;\n return (\n typeof accessToken === 'string' &&\n accessToken !== '' &&\n typeof obtainedAt === 'number' &&\n typeof expiresAt === 'number' &&\n Number.isFinite(obtainedAt) &&\n expiresAt > obtainedAt\n );\n}\n","// Obtención del token ATK de OAuth Token Create.\n// Ver sabre-wiki/wiki/sdk/renovacion-token-oauth.md y wiki/entities/oauth-token-create.md.\nimport type { ResolvedConfig } from '../config.js';\nimport { SabreGatewayError } from '../errors/index.js';\nimport type { AuthorizationProvider, RestTransport } from '../http/rest-transport.js';\nimport { EventLogger } from '../logging/logger.js';\nimport { buildTokenRequest } from './token-request.js';\nimport { isStoredToken, type SabreTokenStore, type StoredToken, tokenStoreKey } from './token-store.js';\n\nexport const TOKEN_SERVICE = 'oauthTokenCreate';\n\n/** Margen de refresco proactivo: 1 h antes de expirar (o media vida si el token dura menos). */\nexport const REFRESH_THRESHOLD_S = 3600;\n\nexport type TokenRefreshReason = 'initial' | 'proactive' | 'reactive';\n\n/** Token ATK obtenido de OAuth Token Create. */\nexport interface AccessToken {\n accessToken: string;\n /** Vida del token en segundos, tal cual llega en `expires_in`. */\n expiresIn: number;\n /** Momento de obtención, en ms desde epoch. */\n obtainedAt: number;\n}\n\ninterface TokenResponse {\n access_token?: unknown;\n expires_in?: unknown;\n token_type?: unknown;\n}\n\nexport interface AuthManagerOptions {\n /** Solo para tests: reloj en ms. */\n now?: () => number;\n}\n\n/**\n * Cachea el token en memoria (y en `tokenStore`, si lo hay), lo renueva antes de que expire\n * y comparte una sola petición en vuelo entre requests concurrentes. Interno en v0.3.0.\n */\nexport class AuthManager {\n readonly #config: ResolvedConfig;\n readonly #transport: RestTransport;\n readonly #now: () => number;\n readonly #log: EventLogger;\n #token: AccessToken | undefined;\n #inFlight: Promise<AccessToken> | undefined;\n /** El último token cacheado fue rechazado con 401 (el próximo refresco es reactivo). */\n #invalidated = false;\n /** Token rechazado con 401: si el store todavía lo tiene, no se vuelve a usar. */\n #rejected: string | undefined;\n readonly #store: SabreTokenStore | undefined;\n #storeKey: Promise<string> | undefined;\n\n constructor(config: ResolvedConfig, transport: RestTransport, options: AuthManagerOptions = {}) {\n this.#config = config;\n this.#transport = transport;\n this.#now = options.now ?? Date.now;\n this.#log = new EventLogger(config.logger);\n this.#store = config.tokenStore;\n }\n\n /** Token vigente; pide uno nuevo si no hay o si cruzó el umbral de refresco. */\n async getToken(): Promise<string> {\n const token = this.#token;\n if (token !== undefined && !this.#needsRefresh(token)) return token.accessToken;\n const reason = token !== undefined ? 'proactive' : this.#invalidated ? 'reactive' : 'initial';\n return (await this.#refresh(reason)).accessToken;\n }\n\n /**\n * Descarta `accessToken` tras un 401 de un servicio. Si el caché ya tiene otro token\n * (otra request lo renovó), no hace nada: los 401 concurrentes comparten un refresco.\n */\n invalidate(accessToken: string): void {\n if (this.#token?.accessToken !== accessToken) return;\n this.#token = undefined;\n this.#invalidated = true;\n this.#rejected = accessToken;\n }\n\n /** Adaptador de salida para el transporte REST: `Authorization: Bearer <token>`. */\n bearerProvider(): AuthorizationProvider {\n return {\n get: async () => `Bearer ${await this.getToken()}`,\n invalidate: (authorization) => this.invalidate(authorization.replace(/^Bearer /, '')),\n };\n }\n\n #needsRefresh(token: AccessToken): boolean {\n const thresholdMs = Math.min(REFRESH_THRESHOLD_S, token.expiresIn / 2) * 1000;\n return this.#now() >= token.obtainedAt + token.expiresIn * 1000 - thresholdMs;\n }\n\n /** Una sola petición en vuelo: las llamadas concurrentes esperan la misma promesa. */\n #refresh(reason: TokenRefreshReason): Promise<AccessToken> {\n this.#inFlight ??= this.#obtain(reason).finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n /** Token del store si sigue vigente (otro proceso pudo renovarlo); si no, uno nuevo. */\n async #obtain(reason: TokenRefreshReason): Promise<AccessToken> {\n const stored = await this.#readStore();\n if (stored !== undefined && stored.accessToken !== this.#rejected && !this.#needsRefresh(stored)) {\n this.#token = stored;\n this.#invalidated = false;\n return stored;\n }\n\n const token = await this.fetchToken();\n this.#token = token;\n this.#invalidated = false;\n this.#rejected = undefined;\n this.#log.emit('info', 'sabre.auth.token.refresh', {\n authVersion: this.#config.authVersion,\n reason,\n expiresIn: token.expiresIn,\n });\n await this.#writeStore(token);\n return token;\n }\n\n async #readStore(): Promise<AccessToken | undefined> {\n if (this.#store === undefined) return undefined;\n try {\n const value = await this.#store.get(await this.#key());\n if (!isStoredToken(value)) return undefined;\n return {\n accessToken: value.accessToken,\n expiresIn: (value.expiresAt - value.obtainedAt) / 1000,\n obtainedAt: value.obtainedAt,\n };\n } catch (error) {\n this.#storeFailed('get', error);\n return undefined;\n }\n }\n\n async #writeStore(token: AccessToken): Promise<void> {\n if (this.#store === undefined) return;\n const stored: StoredToken = {\n accessToken: token.accessToken,\n obtainedAt: token.obtainedAt,\n expiresAt: token.obtainedAt + token.expiresIn * 1000,\n };\n try {\n await this.#store.set(await this.#key(), stored);\n } catch (error) {\n this.#storeFailed('set', error);\n }\n }\n\n #key(): Promise<string> {\n const { environment, authVersion, credentials } = this.#config;\n this.#storeKey ??= tokenStoreKey(environment, authVersion, credentials);\n return this.#storeKey;\n }\n\n /**\n * El store nunca rompe la llamada: se sigue con el caché en memoria. Del error solo se\n * loguea el nombre: el mensaje lo arma el store del consumidor y podría traer el token.\n */\n #storeFailed(operation: 'get' | 'set', error: unknown): void {\n this.#log.emit('warn', 'sabre.auth.token.store', {\n authVersion: this.#config.authVersion,\n operation,\n errorName: error instanceof Error ? error.name : typeof error,\n });\n }\n\n /**\n * Pide un token nuevo. Los errores del endpoint (`invalid_request`/`invalid_client` 401,\n * `unauthorized` 403) salen como `SabreGatewayError` con `retryable: false`.\n */\n async fetchToken(): Promise<AccessToken> {\n const { path, authorization, body } = buildTokenRequest(this.#config.authVersion, this.#config.credentials);\n const response = await this.#transport.request<TokenResponse | undefined>({\n method: 'POST',\n path,\n service: TOKEN_SERVICE,\n // Pedir otro token no tiene efectos duplicados: 429/5xx entran en la política genérica.\n idempotent: true,\n auth: false,\n headers: { Authorization: authorization },\n body,\n });\n return this.#parse(response);\n }\n\n #parse(response: TokenResponse | undefined): AccessToken {\n const accessToken = response?.access_token;\n const expiresIn = response?.expires_in;\n if (typeof accessToken !== 'string' || accessToken === '' || typeof expiresIn !== 'number' || !(expiresIn > 0)) {\n throw new SabreGatewayError(`${TOKEN_SERVICE}: respuesta sin access_token/expires_in válidos`, {\n protocol: 'rest',\n status: 200,\n retryable: false,\n raw: response,\n });\n }\n return { accessToken, expiresIn, obtainedAt: this.#now() };\n }\n}\n","// `errors[]` de la Booking Management API: mismo `Error` del spec en Create, Get y Cancel.\n// Ver sabre-wiki/wiki/sdk/manejo-y-mapeo-de-errores.md.\nimport { SabreBusinessError, SabreWarning } from '../errors/index.js';\n\nconst WARNING = 'WARNING';\n\n/** Elemento de `errors[]` tal cual lo manda Sabre (`Error` del spec; los avisos comparten forma). */\nexport interface BookingResponseError {\n /** `BAD_REQUEST`, `APPLICATION_ERROR`, `WARNING`, … */\n category: string;\n /** P. ej. `UNABLE_TO_BOOK_FLIGHTS`. */\n type: string;\n description?: string;\n fieldPath?: string;\n fieldName?: string;\n /** Puede traer datos del request (p. ej. un email): no se copia a los errores del SDK. */\n fieldValue?: string;\n}\n\nexport function responseErrors(response: { errors?: BookingResponseError[] }): BookingResponseError[] {\n return Array.isArray(response.errors) ? response.errors.filter(isObject) as BookingResponseError[] : [];\n}\n\nexport function isWarning(item: BookingResponseError): boolean {\n return typeof item.category === 'string' && item.category.toUpperCase() === WARNING;\n}\n\nexport function toWarning(service: string, item: BookingResponseError): SabreWarning {\n return new SabreWarning(messageOf(service, item), { service, code: codeOf(item), raw: item });\n}\n\nexport interface BusinessErrorAttachments {\n warnings?: SabreWarning[];\n errors?: SabreBusinessError[];\n retryable?: boolean;\n}\n\nexport function toBusinessError(\n service: string,\n item: BookingResponseError,\n { warnings = [], errors = [], retryable = false }: BusinessErrorAttachments = {},\n): SabreBusinessError {\n return new SabreBusinessError(messageOf(service, item), {\n service,\n code: codeOf(item),\n raw: item,\n warnings,\n errors,\n retryable,\n });\n}\n\nexport function codeOf(item: BookingResponseError): string {\n return typeof item.type === 'string' && item.type !== '' ? item.type : String(item.category);\n}\n\n/** Sin `fieldValue`, que puede traer datos del pasajero; queda en `raw`. */\nfunction messageOf(service: string, item: BookingResponseError): string {\n const where = typeof item.fieldPath === 'string' && item.fieldPath !== '' ? ` en ${item.fieldPath}` : '';\n const description = typeof item.description === 'string' && item.description !== '' ? `: ${item.description}` : '';\n return `${service}: ${String(item.category)} ${codeOf(item)}${where}${description}`;\n}\n\nexport function nonEmpty(value: unknown): value is string {\n return typeof value === 'string' && value !== '';\n}\n\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","// Cancel Booking (`POST /v1/trip/orders/cancelBooking`).\n// Ver sabre-wiki/wiki/sdk/gestion-de-reserva.md y sabre-wiki/wiki/sources/cancel-booking.md.\nimport { SabreError, type SabreWarning } from '../errors/index.js';\nimport type { RestTransport } from '../http/rest-transport.js';\nimport {\n type BookingResponseError,\n isObject,\n isWarning,\n nonEmpty,\n responseErrors,\n toBusinessError,\n toWarning,\n} from './booking-errors.js';\nimport type { Booking } from './create-booking.js';\nimport type { BookingSource } from './get-booking.js';\n\nexport const CANCEL_BOOKING_SERVICE = 'cancelBooking';\nconst PATH = '/v1/trip/orders/cancelBooking';\n/** Llega con `category: WARNING`, pero significa que no se canceló nada (decidido en #39). */\nconst NO_ITEMS_CANCELLED = 'NO_ITEMS_CANCELLED';\nconst ITEM_LISTS = ['flights', 'hotels', 'cars', 'trains', 'cruises', 'segments'] as const;\n\n/** `HALT_ON_ERROR` (default de Sabre, con rollback) o `ALLOW_PARTIAL_CANCEL`. */\nexport type CancelBookingErrorPolicy = 'HALT_ON_ERROR' | 'ALLOW_PARTIAL_CANCEL';\n\nexport type FlightTicketOperation = 'VOID' | 'REFUND';\n\nexport type RefundDocumentsType = 'Tickets' | 'EMDs' | 'Tickets and EMDs';\n\n/** Producto a cancelar, por el `itemId` que devuelve Get Booking (p. ej. `flights[].itemId`). */\nexport interface BookingItemReference {\n itemId: string;\n}\n\n/**\n * Segmento a cancelar, por `id` o por `sequence`. Sabre desaconseja `sequence`: la posición\n * puede cambiar entre la lectura y la cancelación.\n */\nexport interface CancelSegmentReference {\n id?: string;\n sequence?: number;\n}\n\n/** `Notification` del spec: `email` o `queuePlacement`, no los dos. Se envía tal cual. */\nexport interface CancelBookingNotification {\n email?: 'DEFAULT' | 'INVOICE' | 'ETICKET' | 'ETICKET_PDF' | 'ITINERARY' | 'ITINERARY_PDF';\n queuePlacement?: Array<Record<string, unknown>>;\n}\n\n/**\n * `CancelBookingRequest` del spec v1.33. El Tier 1 usa `cancelAll` o `flights[].itemId` sobre\n * contenido ATPCO; los campos de tickets, NDC, impresoras, notificación y retención se envían\n * tal cual, sin lógica propia.\n */\nexport interface CancelBookingRequest {\n /** Localizador del PNR u Order ID (`^[A-Z0-9]{6,}$`). Único campo obligatorio. */\n confirmationId: string;\n bookingSource?: BookingSource;\n /** Cancela todos los segmentos. No se combina con las listas. */\n cancelAll?: boolean;\n flights?: BookingItemReference[];\n hotels?: BookingItemReference[];\n cars?: BookingItemReference[];\n trains?: BookingItemReference[];\n cruises?: BookingItemReference[];\n segments?: CancelSegmentReference[];\n /** Sin valor, Sabre aplica `HALT_ON_ERROR`: si algo falla, deshace lo ya cancelado. */\n errorHandlingPolicy?: CancelBookingErrorPolicy;\n /** Si es `true`, la respuesta trae el estado posterior en `booking`. */\n retrieveBooking?: boolean;\n /** Firma del cambio en el PNR. Sabre usa `LW CANCEL API` por defecto. */\n receivedFrom?: string;\n /** El contexto no se revierte al terminar. */\n targetPcc?: string;\n /** No se combina con `offerItemId`. */\n flightTicketOperation?: FlightTicketOperation;\n /** Solo NDC. No se combina con `flightTicketOperation`. */\n offerItemId?: string;\n notification?: CancelBookingNotification;\n designatePrinters?: Array<Record<string, unknown>>;\n retentionEndDate?: string;\n retentionLabel?: string;\n voidNonElectronicTickets?: boolean;\n refundDocumentsType?: RefundDocumentsType;\n}\n\nexport interface CancelBookingOptions {\n signal?: AbortSignal;\n}\n\n/** `CancelBookingResponse` tal cual llega de Sabre. */\nexport interface RawCancelBookingResponse {\n timestamp?: string;\n request?: CancelBookingRequest;\n booking?: Booking;\n tickets?: Array<Record<string, unknown>>;\n voidedTickets?: string[];\n refundedTickets?: string[];\n flightRefunds?: Array<Record<string, unknown>>;\n errors?: BookingResponseError[];\n}\n\n/** Cancelación con éxito: sin errores fatales y sin `NO_ITEMS_CANCELLED`. */\nexport interface CancelBookingResponse {\n timestamp?: string;\n /** Eco del request con los defaults de Sabre completados. */\n request?: CancelBookingRequest;\n /** Estado posterior de la reserva, anidado (solo con `retrieveBooking: true`). */\n booking?: Booking;\n tickets?: Array<Record<string, unknown>>;\n voidedTickets?: string[];\n refundedTickets?: string[];\n flightRefunds?: Array<Record<string, unknown>>;\n /**\n * Elementos de `errors[]` con `category: WARNING`. Con `END_TRANSACTION_PROBLEM` la\n * confirmación quedó pendiente: verifica el resultado con `sabre.booking.get`.\n */\n warnings: SabreWarning[];\n}\n\n/**\n * Cancel Booking: escritura sin reintento automático. Solo el reintento reactivo ante 401,\n * que el gateway rechaza antes de llegar al proveedor.\n */\nexport async function cancelBooking(\n transport: RestTransport,\n request: CancelBookingRequest,\n options: CancelBookingOptions = {},\n): Promise<CancelBookingResponse> {\n validateCancelBookingRequest(request);\n const body = await transport.request<RawCancelBookingResponse>({\n method: 'POST',\n path: PATH,\n service: CANCEL_BOOKING_SERVICE,\n idempotent: false,\n body: request,\n classify: classifyCancelBooking,\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n });\n return toCancelBookingResponse(body);\n}\n\n/** Combinaciones que Sabre rechaza seguro (`INVALID_FLAGS_COMBINATION`, `CANCEL_DATA_MISSING`). */\nfunction validateCancelBookingRequest(request: CancelBookingRequest): void {\n if (!isObject(request) || !nonEmpty(request.confirmationId)) {\n throw new TypeError('sabre-client: booking.cancel espera { confirmationId: string, ... }');\n }\n const lists = ITEM_LISTS.join(', ');\n if (request.cancelAll === true) {\n if (ITEM_LISTS.some((list) => request[list] !== undefined)) {\n throw new TypeError(`sabre-client: booking.cancel no combina cancelAll con listas (${lists})`);\n }\n } else if (!ITEM_LISTS.some((list) => Array.isArray(request[list]) && request[list].length > 0)) {\n throw new TypeError(`sabre-client: booking.cancel necesita cancelAll: true o al menos una lista (${lists})`);\n }\n if (request.offerItemId !== undefined && request.flightTicketOperation !== undefined) {\n throw new TypeError('sabre-client: booking.cancel no combina offerItemId con flightTicketOperation');\n }\n}\n\n/**\n * Paso 3 del orden de detección. Éxito = ningún error que no sea `WARNING` y ningún\n * `NO_ITEMS_CANCELLED`. Si no:\n *\n * - Con `NO_ITEMS_CANCELLED`: `SabreBusinessError` con ese código; los errores que explican\n * el fallo van en `errors` y los demás avisos en `warnings`.\n * - Sin él: `SabreBusinessError` con el primer error que no sea `WARNING`, el resto en\n * `errors` y los avisos en `warnings`.\n */\nexport function classifyCancelBooking(body: unknown): SabreError | undefined {\n if (!isObject(body)) {\n return new SabreError(`${CANCEL_BOOKING_SERVICE}: respuesta malformada, se esperaba un objeto`, {\n retryable: false,\n raw: body,\n });\n }\n const items = responseErrors(body as RawCancelBookingResponse);\n const nothingCancelled = items.find(isNoItemsCancelled);\n const warnings = items.filter((item) => isWarning(item) && !isNoItemsCancelled(item)).map(warningOf);\n const fatal = items.filter((item) => !isWarning(item));\n\n if (nothingCancelled !== undefined) {\n return toBusinessError(CANCEL_BOOKING_SERVICE, nothingCancelled, { warnings, errors: fatal.map(errorOf) });\n }\n const [first, ...rest] = fatal;\n if (first === undefined) return undefined;\n return toBusinessError(CANCEL_BOOKING_SERVICE, first, { warnings, errors: rest.map(errorOf) });\n}\n\n/** Solo para respuestas con éxito (ver `classifyCancelBooking`): `errors[]` trae solo avisos. */\nfunction toCancelBookingResponse(body: RawCancelBookingResponse): CancelBookingResponse {\n const { errors: _errors, ...rest } = body;\n return { ...rest, warnings: responseErrors(body).map(warningOf) };\n}\n\nfunction isNoItemsCancelled(item: BookingResponseError): boolean {\n return item.type === NO_ITEMS_CANCELLED;\n}\n\nfunction warningOf(item: BookingResponseError): SabreWarning {\n return toWarning(CANCEL_BOOKING_SERVICE, item);\n}\n\nfunction errorOf(item: BookingResponseError) {\n return toBusinessError(CANCEL_BOOKING_SERVICE, item);\n}\n","// Create Booking (`POST /v1/trip/orders/createBooking`).\n// Ver sabre-wiki/wiki/entities/booking-management-api.md y\n// sabre-wiki/wiki/sdk/manejo-y-mapeo-de-errores.md (éxito parcial de Create Booking).\nimport { type SabreBusinessError, SabreError, type SabreWarning } from '../errors/index.js';\nimport type { RestTransport } from '../http/rest-transport.js';\nimport {\n type BookingResponseError,\n isObject,\n isWarning,\n nonEmpty,\n responseErrors,\n toBusinessError,\n toWarning,\n} from './booking-errors.js';\nimport type { CreateBookingRequest } from './create-booking-request.js';\n\nexport const CREATE_BOOKING_SERVICE = 'createBooking';\nconst PATH = '/v1/trip/orders/createBooking';\n/** Aviso cuyo `description` trae el `confirmationId` de una reserva que sí se creó. */\nconst UNABLE_TO_RETRIEVE_BOOKING = 'UNABLE_TO_RETRIEVE_BOOKING';\n\nexport interface CreateBookingOptions {\n signal?: AbortSignal;\n}\n\n/** Elemento de `errors[]` de Create Booking. */\nexport type CreateBookingResponseError = BookingResponseError;\n\n/**\n * `Booking` del spec (mismo modelo que Get Booking). Se tipa el primer nivel; el detalle de\n * `flights`, `travelers`, `fares`, etc. queda sin tipar en el Tier 1.\n */\nexport interface Booking {\n bookingId?: string;\n startDate?: string;\n endDate?: string;\n isCancelable?: boolean;\n isTicketed?: boolean;\n [field: string]: unknown;\n}\n\n/** `CreateBookingResponse` tal cual llega de Sabre. */\nexport interface RawCreateBookingResponse {\n timestamp?: string;\n confirmationId?: string;\n booking?: Booking;\n errors?: CreateBookingResponseError[];\n request?: CreateBookingRequest;\n}\n\n/**\n * Reserva creada. Si Sabre la creó con avisos o con errores no fatales (p. ej. con\n * `errorHandlingPolicy: DO_NOT_HALT_ON_*`), no se lanza: van adjuntos aquí.\n */\nexport interface CreateBookingResponse {\n /** Localizador del PNR. */\n confirmationId: string;\n timestamp?: string;\n /** Falta, p. ej., con el aviso `UNABLE_TO_RETRIEVE_BOOKING`. */\n booking?: Booking;\n /** Copia del request enviado, si Sabre la devuelve. */\n request?: CreateBookingRequest;\n /** Elementos de `errors[]` con `category: WARNING`. */\n warnings: SabreWarning[];\n /** Elementos de `errors[]` de otras categorías que no impidieron crear la reserva. */\n errors: SabreBusinessError[];\n}\n\n/**\n * Create Booking: escritura no idempotente, sin reintento automático. Solo el reintento\n * reactivo ante 401, que el gateway rechaza antes de llegar al proveedor.\n */\nexport async function createBooking(\n transport: RestTransport,\n request: CreateBookingRequest,\n options: CreateBookingOptions = {},\n): Promise<CreateBookingResponse> {\n if (typeof request !== 'object' || request === null) {\n throw new TypeError('sabre-client: booking.create espera un objeto CreateBookingRequest');\n }\n const body = await transport.request<RawCreateBookingResponse>({\n method: 'POST',\n path: PATH,\n service: CREATE_BOOKING_SERVICE,\n idempotent: false,\n body: request,\n classify: classifyCreateBooking,\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n });\n return toCreateBookingResponse(body);\n}\n\n/**\n * Paso 3 del orden de detección. Lo que decide si se lanza es si la reserva se creó, no la\n * categoría de `errors[]`:\n *\n * - Hay reserva (`confirmationId`, `booking.bookingId` o el aviso `UNABLE_TO_RETRIEVE_BOOKING`\n * con el localizador en el `description`): no hay error, `toCreateBookingResponse` adjunta\n * avisos y errores al resultado.\n * - No hay reserva: `SabreBusinessError` con el primer error que no sea `WARNING`, y los\n * avisos adjuntos.\n */\nexport function classifyCreateBooking(body: unknown): SabreError | undefined {\n if (!isObject(body)) {\n return new SabreError(`${CREATE_BOOKING_SERVICE}: respuesta malformada, se esperaba un objeto`, {\n retryable: false,\n raw: body,\n });\n }\n const response = body as RawCreateBookingResponse;\n if (confirmationIdOf(response) !== undefined) return undefined;\n\n // La reserva existe pero no hay localizador que devolver: no es un \"no se creó\".\n if (reservationWithoutId(response)) {\n return new SabreError(\n `${CREATE_BOOKING_SERVICE}: Sabre indica que la reserva se creó, pero no devolvió su confirmationId`,\n { retryable: false, raw: body },\n );\n }\n const items = responseErrors(response);\n const fatal = items.find((item) => !isWarning(item));\n if (fatal !== undefined) return toBusinessError(CREATE_BOOKING_SERVICE, fatal, { warnings: items.filter(isWarning).map(warningOf) });\n return new SabreError(`${CREATE_BOOKING_SERVICE}: respuesta malformada, sin confirmationId ni errores fatales`, {\n retryable: false,\n raw: body,\n });\n}\n\n/** Solo para respuestas con reserva (ver `classifyCreateBooking`). */\nfunction toCreateBookingResponse(body: RawCreateBookingResponse): CreateBookingResponse {\n const items = responseErrors(body);\n return {\n confirmationId: confirmationIdOf(body)!,\n ...(body.timestamp === undefined ? {} : { timestamp: body.timestamp }),\n ...(body.booking === undefined ? {} : { booking: body.booking }),\n ...(body.request === undefined ? {} : { request: body.request }),\n warnings: items.filter(isWarning).map(warningOf),\n errors: items.filter((item) => !isWarning(item)).map((item) => toBusinessError(CREATE_BOOKING_SERVICE, item)),\n };\n}\n\nfunction confirmationIdOf(response: RawCreateBookingResponse): string | undefined {\n if (nonEmpty(response.confirmationId)) return response.confirmationId;\n if (nonEmpty(response.booking?.bookingId)) return response.booking.bookingId;\n const notRetrieved = responseErrors(response).find((item) => item.type === UNABLE_TO_RETRIEVE_BOOKING);\n return notRetrieved === undefined ? undefined : locatorIn(notRetrieved.description);\n}\n\nfunction reservationWithoutId(response: RawCreateBookingResponse): boolean {\n return response.booking !== undefined || responseErrors(response).some((item) => item.type === UNABLE_TO_RETRIEVE_BOOKING);\n}\n\n/**\n * El catálogo documenta el description como `Booking was created successfully but could not\n * be retrieved. (confirmationId)`. Se prefiere el valor entre paréntesis.\n */\nfunction locatorIn(description: string | undefined): string | undefined {\n if (description === undefined) return undefined;\n return /\\(([A-Z0-9]{6,})\\)/.exec(description)?.[1] ?? /\\b([A-Z0-9]{6,})\\b/.exec(description)?.[1];\n}\n\nfunction warningOf(item: BookingResponseError): SabreWarning {\n return toWarning(CREATE_BOOKING_SERVICE, item);\n}\n","// Get Booking (`POST /v1/trip/orders/getBooking`).\n// Ver sabre-wiki/wiki/sdk/gestion-de-reserva.md y sabre-wiki/wiki/sources/get-booking.md.\nimport { type SabreBusinessError, SabreError, type SabreWarning } from '../errors/index.js';\nimport type { RestTransport } from '../http/rest-transport.js';\nimport {\n type BookingResponseError,\n isObject,\n isWarning,\n nonEmpty,\n responseErrors,\n toBusinessError,\n toWarning,\n} from './booking-errors.js';\nimport type { Booking } from './create-booking.js';\n\nexport const GET_BOOKING_SERVICE = 'getBooking';\nconst PATH = '/v1/trip/orders/getBooking';\n/** Fallos de sistema que Sabre puede resolver al repetir la lectura (decidido en #39). */\nconst RETRYABLE_TYPES = new Set(['INTERNAL_SERVER_TIMEOUT', 'DOWNLINE_SERVICE_FAILURE']);\n\n/** Secciones de la respuesta (`ReturnOnlyEnum`). Además evitan llamadas downline de Sabre. */\nexport type GetBookingReturnOnly =\n | 'FLIGHTS'\n | 'FLIGHT_PENALTY'\n | 'BAGGAGE_POLICY'\n | 'JOURNEYS'\n | 'HOTELS'\n | 'HOTEL_ADDRESS'\n | 'CARS'\n | 'CAR_RENTAL_ADDRESS'\n | 'CAR_RENTAL_PENALTY'\n | 'TRAINS'\n | 'CRUISES'\n | 'ALL_SEGMENTS'\n | 'TRAVELERS'\n | 'TICKETS'\n | 'PAYMENTS'\n | 'PENALTIES'\n | 'REMARKS'\n | 'IS_CANCELABLE'\n | 'IS_TICKETED'\n | 'CONTACT_INFO'\n | 'OTHER_SERVICES'\n | 'SPECIAL_SERVICES'\n | 'FARES'\n | 'CREATION_DETAILS'\n | 'ANCILLARIES'\n | 'FORMS_OF_PAYMENT'\n | 'RETENTION_DATE'\n | 'ACCOUNTING_ITEMS'\n | 'NON_ELECTRONIC_TICKETS'\n | 'TRAVELERS_EMPLOYERS'\n | 'PROFILES';\n\n/** `BookingSourceEnum`. Por defecto `SABRE`. */\nexport type BookingSource = 'SABRE' | 'SABRE_ORDER';\n\n/** `ExtraFeatures` del spec (incluye `CommonExtraFeatures`). */\nexport interface GetBookingExtraFeatures {\n /** Solo NDC. Por defecto `true`. */\n returnEmptySeatObjects?: boolean;\n /** Por defecto `false`; más lento. */\n forceHotelUpdate?: boolean;\n returnFrequentRenter?: boolean;\n returnWalletFormsOfPayment?: boolean;\n returnFiscalId?: boolean;\n}\n\n/** `GetBookingRequest` del spec v1.33. */\nexport interface GetBookingRequest {\n /** Localizador del PNR u Order ID (`^[A-Z0-9]{6,}$`). Único campo obligatorio. */\n confirmationId: string;\n bookingSource?: BookingSource;\n /** Cambio de contexto (`^[A-Z0-9]{3,4}$`). */\n targetPcc?: string;\n /** Validación extra: si no coincide con el PNR, Sabre responde `UNAUTHORIZED_ACCESS`. */\n surname?: string;\n /** Según el spec, Sabre no los usa; solo `surname`. */\n givenName?: string;\n middleName?: string;\n /** Vacío o ausente: la reserva completa. */\n returnOnly?: GetBookingReturnOnly[];\n extraFeatures?: GetBookingExtraFeatures;\n /** Requiere el keyword `CCVIEW` en el EPR. */\n unmaskPaymentCardNumbers?: boolean;\n}\n\nexport interface GetBookingOptions {\n signal?: AbortSignal;\n}\n\n/** `GetBookingResponse` tal cual llega de Sabre: el `Booking` va en el primer nivel. */\nexport interface RawGetBookingResponse extends Booking {\n timestamp?: string;\n bookingSignature?: string;\n request?: GetBookingRequest;\n errors?: BookingResponseError[];\n}\n\n/**\n * Reserva leída, con el `Booking` en el primer nivel tal cual lo define Sabre (no se normaliza\n * contra Create ni Cancel, que lo anidan en `booking`). `errors[]` del original se reemplaza\n * por los errores del SDK.\n */\nexport interface GetBookingResponse extends Booking {\n bookingId: string;\n timestamp?: string;\n /** Solo viene si Sabre armó la reserva sin errores. Lo usa Modify Booking. */\n bookingSignature?: string;\n /** Copia del request enviado, si Sabre la devuelve. */\n request?: GetBookingRequest;\n /**\n * Elementos de `errors[]` con `category: WARNING`. En un PNR sin emitir es normal\n * `RESOURCE_UNAVAILABLE` por falta de fare rules.\n */\n warnings: SabreWarning[];\n /**\n * Elementos de `errors[]` de otras categorías que llegaron junto con la reserva, p. ej.\n * `UNAUTHORIZED_ACCESS` de un servicio downline: faltan secciones, pero la reserva existe.\n */\n errors: SabreBusinessError[];\n}\n\n/**\n * Get Booking: lectura idempotente. Los 429/5xx de gateway se reintentan con la política\n * genérica, y también `INTERNAL_SERVER_TIMEOUT` y `DOWNLINE_SERVICE_FAILURE`.\n */\nexport async function getBooking(\n transport: RestTransport,\n request: GetBookingRequest,\n options: GetBookingOptions = {},\n): Promise<GetBookingResponse> {\n if (!isObject(request) || !nonEmpty(request.confirmationId)) {\n throw new TypeError('sabre-client: booking.get espera { confirmationId: string, ... }');\n }\n const body = await transport.request<RawGetBookingResponse>({\n method: 'POST',\n path: PATH,\n service: GET_BOOKING_SERVICE,\n idempotent: true,\n body: request,\n classify: classifyGetBooking,\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n });\n return toGetBookingResponse(body);\n}\n\n/**\n * Paso 3 del orden de detección. Lo que decide si se lanza es si hay reserva (`bookingId`):\n *\n * - Hay reserva: no hay error; `toGetBookingResponse` adjunta avisos y errores al resultado.\n * - No hay reserva: `SabreBusinessError` con el primer error que no sea `WARNING` (p. ej.\n * `BOOKING_NOT_FOUND` o `UNAUTHORIZED_ACCESS`), y los avisos adjuntos.\n */\nexport function classifyGetBooking(body: unknown): SabreError | undefined {\n if (!isObject(body)) {\n return new SabreError(`${GET_BOOKING_SERVICE}: respuesta malformada, se esperaba un objeto`, {\n retryable: false,\n raw: body,\n });\n }\n const response = body as RawGetBookingResponse;\n if (nonEmpty(response.bookingId)) return undefined;\n\n const items = responseErrors(response);\n const fatal = items.find((item) => !isWarning(item));\n if (fatal !== undefined) return errorOf(fatal, items.filter(isWarning).map(warningOf));\n return new SabreError(`${GET_BOOKING_SERVICE}: respuesta malformada, sin bookingId ni errores fatales`, {\n retryable: false,\n raw: body,\n });\n}\n\n/** Solo para respuestas con reserva (ver `classifyGetBooking`). */\nfunction toGetBookingResponse(body: RawGetBookingResponse): GetBookingResponse {\n const items = responseErrors(body);\n return {\n ...body,\n bookingId: body.bookingId!,\n warnings: items.filter(isWarning).map(warningOf),\n errors: items.filter((item) => !isWarning(item)).map((item) => errorOf(item, [])),\n };\n}\n\nfunction warningOf(item: BookingResponseError): SabreWarning {\n return toWarning(GET_BOOKING_SERVICE, item);\n}\n\nfunction errorOf(item: BookingResponseError, warnings: SabreWarning[]): SabreBusinessError {\n return toBusinessError(GET_BOOKING_SERVICE, item, { warnings, retryable: RETRYABLE_TYPES.has(item.type) });\n}\n","// Módulo de dominio `sabre.booking` (Booking Management API).\n// Ver sabre-wiki/wiki/sdk/convenciones-de-nombres-y-versionado.md.\nimport type { RestTransport } from '../http/rest-transport.js';\nimport {\n cancelBooking,\n type CancelBookingOptions,\n type CancelBookingRequest,\n type CancelBookingResponse,\n} from './cancel-booking.js';\nimport type { CreateBookingRequest } from './create-booking-request.js';\nimport { createBooking, type CreateBookingOptions, type CreateBookingResponse } from './create-booking.js';\nimport { getBooking, type GetBookingOptions, type GetBookingRequest, type GetBookingResponse } from './get-booking.js';\n\nexport class BookingManagement {\n readonly #transport: RestTransport;\n\n /** @internal Lo construye el cliente `Sabre`. */\n constructor(transport: RestTransport) {\n this.#transport = transport;\n }\n\n /**\n * Create Booking: crea la reserva. Para un itinerario de BFM/Revalidate, `flightDetails` se\n * arma con `buildBookingFlightDetails`.\n *\n * Nunca se reintenta automáticamente. Si la reserva se crea con avisos o errores no fatales,\n * no lanza: los devuelve en `warnings` y `errors`. Si no se crea, lanza `SabreBusinessError`.\n */\n create(request: CreateBookingRequest, options?: CreateBookingOptions): Promise<CreateBookingResponse> {\n return createBooking(this.#transport, request, options);\n }\n\n /**\n * Get Booking: lee la reserva por `confirmationId`. El `Booking` va en el primer nivel de la\n * respuesta, a diferencia de `create`. Usa `returnOnly` para pedir solo las secciones que\n * hacen falta: además acelera la respuesta.\n *\n * Si la reserva existe, no lanza: los avisos y errores parciales van en `warnings` y\n * `errors`. Si no existe o no se pudo leer (p. ej. `BOOKING_NOT_FOUND`), lanza\n * `SabreBusinessError`. Es una lectura: se reintenta ante fallos transitorios.\n */\n get(request: GetBookingRequest, options?: GetBookingOptions): Promise<GetBookingResponse> {\n return getBooking(this.#transport, request, options);\n }\n\n /**\n * Cancel Booking: cancela la reserva entera (`cancelAll: true`) o por `itemId` (p. ej. los\n * `flights[].itemId` de `get`). Valida antes de enviar las combinaciones que Sabre rechaza y,\n * si encuentra una, lanza `TypeError` sin llamar a la red.\n *\n * Nunca se reintenta automáticamente. Lanza `SabreBusinessError` si algo falló o si Sabre\n * responde `NO_ITEMS_CANCELLED` (no se canceló nada), aunque llegue como aviso. Con\n * `END_TRANSACTION_PROBLEM` en `warnings`, la confirmación quedó pendiente: verifica con `get`.\n */\n cancel(request: CancelBookingRequest, options?: CancelBookingOptions): Promise<CancelBookingResponse> {\n return cancelBooking(this.#transport, request, options);\n }\n}\n","// Política de reintentos. Ver sabre-wiki/wiki/sdk/politica-de-reintentos-y-backoff.md.\nimport { SabreError } from '../errors/index.js';\n\nexport interface RetryOptions {\n /** Reintentos después de la primera llamada (3 → hasta 4 llamadas en total). */\n maxRetries: number;\n /** Delay base del backoff exponencial, en milisegundos. */\n baseDelayMs: number;\n}\n\nexport const DEFAULT_RETRY: Readonly<RetryOptions> = Object.freeze({ maxRetries: 3, baseDelayMs: 500 });\n\n/** Piso mínimo de espera que documenta Sabre para 429/5xx de gateway. */\nexport const MIN_RETRY_DELAY_MS = 500;\n\n/** Full jitter: aleatorio entre 0 y `baseDelayMs · 2^retry`, con piso de 500 ms. */\nexport function retryDelay(retry: number, baseDelayMs: number, random: () => number = Math.random): number {\n return Math.max(MIN_RETRY_DELAY_MS, Math.floor(random() * baseDelayMs * 2 ** retry));\n}\n\n/** Solo se reintenta un `SabreError` con `retryable: true` en una operación idempotente. */\nexport function shouldRetry(error: unknown, idempotent: boolean): boolean {\n return idempotent && error instanceof SabreError && error.retryable;\n}\n\nexport function validateRetryOptions(retry: Partial<RetryOptions>, where: string): void {\n if (retry.maxRetries !== undefined && !(Number.isInteger(retry.maxRetries) && retry.maxRetries >= 0)) {\n throw new TypeError(`sabre-client: ${where}.maxRetries debe ser un entero >= 0`);\n }\n if (retry.baseDelayMs !== undefined && !(Number.isFinite(retry.baseDelayMs) && retry.baseDelayMs >= 0)) {\n throw new TypeError(`sabre-client: ${where}.baseDelayMs debe ser un número >= 0`);\n }\n}\n","// Config explícita del consumidor; el SDK nunca lee variables de entorno.\n// Ver sabre-wiki/wiki/sdk/configuracion-logging-y-build.md.\nimport type { SabreTokenStore } from './auth/token-store.js';\nimport { DEFAULT_RETRY, type RetryOptions, validateRetryOptions } from './http/retry.js';\nimport type { SabreLogger } from './logging/index.js';\n\nexport type SabreEnvironment = 'sandbox' | 'production';\n\nexport type SabreAuthVersion = 'v3' | 'v2';\n\n/** Credenciales para OAuth Token Create v3: Client ID/Secret más usuario EPR. */\nexport interface SabreCredentials {\n clientId: string;\n clientSecret: string;\n /** Usuario EPR. */\n username: string;\n /** Contraseña EPR. */\n password: string;\n}\n\n/** Credenciales para OAuth Token Create v2: solo EPR; `clientId`/`clientSecret` se ignoran. */\nexport interface SabreCredentialsV2 {\n clientId?: string;\n clientSecret?: string;\n /** Usuario EPR. */\n username: string;\n /** Contraseña EPR. */\n password: string;\n}\n\ninterface SabreBaseConfig {\n environment: SabreEnvironment;\n /** Campo reservado: PCC vs iPCC sigue sin resolver. */\n pcc?: string;\n logger?: SabreLogger;\n /** Reintentos por defecto del cliente; cada request puede pisarlos. */\n retry?: Partial<RetryOptions>;\n /** `fetch` a usar en lugar del global (tests, proxies, runtimes edge). */\n fetch?: typeof fetch;\n /**\n * Almacén del token para reutilizarlo entre procesos (scripts, serverless). Sin él, el\n * token se cachea solo en memoria.\n */\n tokenStore?: SabreTokenStore;\n}\n\n/** OAuth Token Create v3 (por defecto). */\nexport interface SabreConfigV3 extends SabreBaseConfig {\n authVersion?: 'v3';\n credentials: SabreCredentials;\n}\n\n/** OAuth Token Create v2. */\nexport interface SabreConfigV2 extends SabreBaseConfig {\n authVersion: 'v2';\n credentials: SabreCredentialsV2;\n}\n\n/** Config del cliente, discriminada por `authVersion`. */\nexport type SabreConfig = SabreConfigV3 | SabreConfigV2;\n\nexport const BASE_URLS: Readonly<Record<SabreEnvironment, string>> = Object.freeze({\n sandbox: 'https://api.cert.platform.sabre.com',\n production: 'https://api.platform.sabre.com',\n});\n\n/** Config validada y con defaults aplicados. */\nexport interface ResolvedConfig {\n credentials: Readonly<SabreCredentials | SabreCredentialsV2>;\n environment: SabreEnvironment;\n baseUrl: string;\n authVersion: SabreAuthVersion;\n pcc: string | undefined;\n logger: SabreLogger | undefined;\n retry: Readonly<RetryOptions>;\n fetch: typeof fetch;\n tokenStore: SabreTokenStore | undefined;\n}\n\nconst LOGGER_METHODS = ['debug', 'info', 'warn', 'error'] as const;\n\nfunction fail(message: string): never {\n throw new TypeError(`sabre-client: ${message}`);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction requireString(value: unknown, field: string): void {\n if (typeof value !== 'string' || value.trim() === '') fail(`${field} es requerido y debe ser un string no vacío`);\n}\n\nexport function resolveConfig(config: SabreConfig): ResolvedConfig {\n if (!isObject(config)) fail('la config debe ser un objeto');\n\n const { environment } = config;\n if (environment !== 'sandbox' && environment !== 'production') {\n fail(`environment debe ser 'sandbox' o 'production' (recibido: ${JSON.stringify(environment)})`);\n }\n\n const authVersion = config.authVersion ?? 'v3';\n if (authVersion !== 'v3' && authVersion !== 'v2') {\n fail(`authVersion debe ser 'v3' o 'v2' (recibido: ${JSON.stringify(authVersion)})`);\n }\n\n const { credentials } = config;\n if (!isObject(credentials)) fail('credentials es requerido');\n requireString(credentials.username, 'credentials.username');\n requireString(credentials.password, 'credentials.password');\n if (authVersion === 'v3') {\n requireString(credentials.clientId, 'credentials.clientId (requerido con authVersion v3)');\n requireString(credentials.clientSecret, 'credentials.clientSecret (requerido con authVersion v3)');\n }\n\n if (config.pcc !== undefined) requireString(config.pcc, 'pcc');\n\n const { logger } = config;\n if (logger !== undefined) {\n if (!isObject(logger)) fail('logger debe ser un objeto con debug/info/warn/error');\n for (const method of LOGGER_METHODS) {\n if (typeof logger[method] !== 'function') fail(`logger.${method} debe ser una función`);\n }\n }\n\n if (config.retry !== undefined) {\n if (!isObject(config.retry)) fail('retry debe ser un objeto');\n validateRetryOptions(config.retry, 'retry');\n }\n\n const { tokenStore } = config;\n if (tokenStore !== undefined) {\n if (!isObject(tokenStore) || typeof tokenStore.get !== 'function' || typeof tokenStore.set !== 'function') {\n fail('tokenStore debe ser un objeto con get(key) y set(key, token)');\n }\n }\n\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') fail('no hay fetch disponible: pasa config.fetch');\n\n return {\n credentials: Object.freeze({ ...credentials }),\n environment,\n baseUrl: BASE_URLS[environment],\n authVersion,\n pcc: config.pcc,\n logger,\n retry: Object.freeze({ ...DEFAULT_RETRY, ...definedOnly(config.retry ?? {}) }),\n // Enlazado al global para evitar \"Illegal invocation\" en algunos runtimes.\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n tokenStore,\n };\n}\n\n/** Quita claves con valor `undefined` para que no pisen los defaults. */\nexport function definedOnly<T extends object>(value: T): Partial<T> {\n return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n","// Transporte REST del cliente `Sabre`: fetch JSON, detección de errores y reintentos.\n// Ver sabre-wiki/wiki/sdk/manejo-y-mapeo-de-errores.md y politica-de-reintentos-y-backoff.md.\nimport { definedOnly, type ResolvedConfig } from '../config.js';\nimport { SabreError, SabreGatewayError } from '../errors/index.js';\nimport { EventLogger } from '../logging/logger.js';\nimport { type RetryOptions, retryDelay, shouldRetry, validateRetryOptions } from './retry.js';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n/** Status de gateway REST reintentables (ver errores-comunes-api). */\nconst RETRYABLE_STATUS = new Set([429, 500, 503, 504]);\n\n/**\n * Pasos 2–3 del orden de detección, aportados por cada servicio: recibe el body de una\n * respuesta 2xx y devuelve el error de su catálogo (orquestado, negocio o warning), o\n * `undefined` si la respuesta es data válida.\n */\nexport type ResponseClassifier = (body: unknown, response: Response) => SabreError | undefined;\n\nexport interface RestRequest {\n method: HttpMethod;\n /** Ruta relativa a la base URL, p. ej. `/v5/offers/shop`. */\n path: string;\n /** Nombre del servicio para errores y logs, p. ej. `'bargainFinderMax'`. */\n service: string;\n /**\n * Si la operación se puede repetir sin efectos duplicados. Las escrituras\n * (Create Booking, End Transaction) van en `false` y nunca se reintentan.\n */\n idempotent: boolean;\n query?: Record<string, string | number | boolean | undefined>;\n /** Se serializa como JSON, salvo `URLSearchParams`, que va como form-urlencoded. */\n body?: unknown;\n headers?: Record<string, string>;\n /** `false` para no pedir el header `Authorization` (p. ej. la propia request de token). */\n auth?: boolean;\n classify?: ResponseClassifier;\n retry?: Partial<RetryOptions>;\n signal?: AbortSignal;\n}\n\n/** Fuente del header `Authorization` de los servicios (la implementa `AuthManager`). */\nexport interface AuthorizationProvider {\n /** Valor vigente del header, p. ej. `Bearer <token>`. */\n get(): Promise<string>;\n /** El gateway rechazó `authorization` con 401: descartarlo para que `get` traiga otro. */\n invalidate(authorization: string): void;\n}\n\nexport interface RestTransportOptions {\n authorization?: AuthorizationProvider;\n /** Solo para tests: fuente de aleatoriedad del jitter. */\n random?: () => number;\n /** Solo para tests: espera entre reintentos. */\n sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;\n}\n\nexport class RestTransport {\n readonly #config: ResolvedConfig;\n readonly #log: EventLogger;\n readonly #random: () => number;\n readonly #sleep: (ms: number, signal?: AbortSignal) => Promise<void>;\n #authorization: AuthorizationProvider | undefined;\n\n constructor(config: ResolvedConfig, options: RestTransportOptions = {}) {\n this.#config = config;\n this.#log = new EventLogger(config.logger);\n this.#authorization = options.authorization;\n this.#random = options.random ?? Math.random;\n this.#sleep = options.sleep ?? sleep;\n }\n\n /** Punto de enganche para `AuthManager`. */\n setAuthorizationProvider(provider: AuthorizationProvider | undefined): void {\n this.#authorization = provider;\n }\n\n async request<T>(request: RestRequest): Promise<T> {\n if (request.retry !== undefined) validateRetryOptions(request.retry, 'retry');\n const retry = { ...this.#config.retry, ...definedOnly(request.retry ?? {}) };\n\n let reauthorized = false;\n for (let attempt = 0; ; attempt++) {\n // Fuera del try: un fallo al obtener el token ya pasó por sus propios reintentos.\n const authorization = await this.#authorizationFor(request);\n try {\n return await this.#send<T>(request, attempt, authorization);\n } catch (error) {\n // Refresco reactivo: un solo reintento con token nuevo, fuera del presupuesto genérico.\n // Aplica también a escrituras: el 401 del gateway rechaza la request antes del proveedor.\n if (authorization !== undefined && !reauthorized && isUnauthorized(error)) {\n reauthorized = true;\n this.#authorization?.invalidate(authorization);\n this.#log.emit('warn', 'sabre.request.retry', {\n service: request.service,\n method: request.method,\n path: request.path,\n attempt: attempt + 1,\n reason: 'unauthorized',\n error: error as SabreError,\n });\n attempt--;\n continue;\n }\n if (attempt >= retry.maxRetries || !shouldRetry(error, request.idempotent)) throw error;\n const delayMs = retryDelay(attempt, retry.baseDelayMs, this.#random);\n this.#log.emit('warn', 'sabre.request.retry', {\n service: request.service,\n method: request.method,\n path: request.path,\n attempt: attempt + 1,\n maxRetries: retry.maxRetries,\n delayMs,\n error: error as SabreError,\n });\n await this.#sleep(delayMs, request.signal);\n }\n }\n }\n\n async #authorizationFor(request: RestRequest): Promise<string | undefined> {\n if (request.auth === false || this.#authorization === undefined) return undefined;\n return this.#authorization.get();\n }\n\n async #send<T>(request: RestRequest, attempt: number, authorization: string | undefined): Promise<T> {\n const url = this.#url(request);\n const headers = new Headers({ Accept: 'application/json', ...request.headers });\n const form = request.body instanceof URLSearchParams;\n if (request.body !== undefined && !headers.has('Content-Type')) {\n headers.set('Content-Type', form ? 'application/x-www-form-urlencoded' : 'application/json');\n }\n if (authorization !== undefined) headers.set('Authorization', authorization);\n\n const logContext = { service: request.service, method: request.method, path: request.path, attempt };\n this.#log.emit('debug', 'sabre.request.start', logContext);\n const startedAt = Date.now();\n\n let response: Response;\n try {\n response = await this.#config.fetch(url, {\n method: request.method,\n headers,\n ...(request.body === undefined ? {} : { body: form ? String(request.body) : JSON.stringify(request.body) }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n });\n } catch (cause) {\n if (isAbort(cause, request.signal)) throw cause;\n const error = new SabreGatewayError(`${request.service}: fallo de red (${describe(cause)})`, {\n protocol: 'rest',\n retryable: true,\n cause,\n });\n this.#log.emit('error', 'sabre.request.end', { ...logContext, durationMs: Date.now() - startedAt, error });\n throw error;\n }\n\n const body = await readBody(response);\n const endContext = { ...logContext, status: response.status, durationMs: Date.now() - startedAt };\n\n // Paso 1: HTTP status de gateway.\n if (!response.ok) {\n const error = gatewayError(request.service, response.status, body);\n this.#log.emit('error', 'sabre.request.end', { ...endContext, error });\n throw error;\n }\n\n // Pasos 2–3: catálogo propio del servicio.\n const serviceError = request.classify?.(body, response);\n if (serviceError !== undefined) {\n this.#log.emit('warn', 'sabre.request.end', { ...endContext, error: serviceError });\n throw serviceError;\n }\n\n // Paso 4: data.\n this.#log.emit('info', 'sabre.request.end', endContext);\n return body as T;\n }\n\n #url(request: RestRequest): string {\n const path = request.path.startsWith('/') ? request.path : `/${request.path}`;\n const url = new URL(path, this.#config.baseUrl);\n for (const [key, value] of Object.entries(request.query ?? {})) {\n if (value !== undefined) url.searchParams.set(key, String(value));\n }\n return url.toString();\n }\n}\n\n/** Body parseado como JSON; si no es JSON, el texto tal cual; vacío → `undefined`. */\nasync function readBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (text === '') return undefined;\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return text;\n }\n}\n\nfunction gatewayError(service: string, status: number, body: unknown): SabreGatewayError {\n const code = extractCode(body);\n return new SabreGatewayError(`${service}: HTTP ${status}${code === undefined ? '' : ` ${code}`}`, {\n protocol: 'rest',\n status,\n retryable: RETRYABLE_STATUS.has(status),\n raw: body,\n ...(code === undefined ? {} : { code }),\n });\n}\n\n/**\n * Best-effort: el campo exacto del código `ERR.2SG.*` no está confirmado\n * (issue de fuente #21). Se prueban `errorCode` y `error`.\n */\nfunction extractCode(body: unknown): string | undefined {\n if (typeof body !== 'object' || body === null) return undefined;\n for (const key of ['errorCode', 'error'] as const) {\n const value = (body as Record<string, unknown>)[key];\n if (typeof value === 'string' && value !== '') return value;\n }\n return undefined;\n}\n\nfunction isUnauthorized(error: unknown): boolean {\n return error instanceof SabreGatewayError && error.protocol === 'rest' && error.status === 401;\n}\n\nfunction isAbort(error: unknown, signal: AbortSignal | undefined): boolean {\n return signal?.aborted === true || (error instanceof Error && error.name === 'AbortError');\n}\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(signal.reason);\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n reject(signal?.reason);\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","// Cliente REST. Ver sabre-wiki/wiki/sdk/arquitectura-clientes-transporte.md.\nimport { Air } from './air/air.js';\nimport { AuthManager } from './auth/auth-manager.js';\nimport { BookingManagement } from './booking/booking-management.js';\nimport { type ResolvedConfig, resolveConfig, type SabreConfig, type SabreEnvironment } from './config.js';\nimport { RestTransport } from './http/rest-transport.js';\n\nexport class Sabre {\n readonly #config: ResolvedConfig;\n readonly #transport: RestTransport;\n /** Servicios de Air: shopping, revalidación. */\n readonly air: Air;\n /** Booking Management: creación de reservas. */\n readonly booking: BookingManagement;\n\n constructor(config: SabreConfig) {\n this.#config = resolveConfig(config);\n this.#transport = new RestTransport(this.#config);\n // Toda request lleva `Authorization: Bearer <token>`, salvo la propia de token (`auth: false`).\n const auth = new AuthManager(this.#config, this.#transport);\n this.#transport.setAuthorizationProvider(auth.bearerProvider());\n this.air = new Air(this.#transport);\n this.booking = new BookingManagement(this.#transport);\n }\n\n get environment(): SabreEnvironment {\n return this.#config.environment;\n }\n\n get baseUrl(): string {\n return this.#config.baseUrl;\n }\n}\n","// Armado de `flightDetails` de Create Booking desde un itinerario de BFM/Revalidate.\n// El mapeo está inferido, ninguna fuente lo documenta: ver la tabla \"Mapeo desde un\n// itinerario de BFM/Revalidate → flightDetails\" en sabre-wiki/wiki/entities/booking-management-api.md.\nimport type { Itinerary, ItineraryGroup } from '../air/grouped-itinerary.js';\nimport { itineraryFlights } from '../air/itinerary-flights.js';\nimport type { FlightDetails, FlightToBook, PassengerPricing, PriceComparison } from './create-booking-request.js';\n\nexport interface BookingFlightDetailsSource {\n /** Grupo del itinerario: aporta la fecha de cada tramo. */\n group: ItineraryGroup;\n /** Itinerario elegido, idealmente el devuelto por Revalidate Itinerary. */\n itinerary: Itinerary;\n /**\n * Umbral de precio. `desiredAmount` sale de `totalFare.totalPrice` del itinerario. El spec no\n * tiene campo de moneda: se supone la del pricing (la del PCC, salvo `currencyPricing`).\n */\n priceComparison?: Omit<PriceComparison, 'desiredAmount'>;\n}\n\n/**\n * Arma `flightDetails` para reservar por el camino ATPCO un itinerario ya revalidado.\n *\n * - `flights[]`: vuelo comercializador, aeropuertos, fecha y clase con las mismas reglas que\n * Revalidate (`itineraryFlights`); `departureTime` en `HH:MM` y `flightStatusCode: 'NN'`.\n * `isMarriageGroup` no se manda: no hay fuente para él.\n * - `flightPricing[0].qualifiers`: `passengersPricing` desde `passengerInfoList` y\n * `validatingAirlineCode` desde `validatingCarrierCode` de la primera cotización.\n */\nexport function buildBookingFlightDetails(source: BookingFlightDetailsSource): FlightDetails {\n const { group, itinerary, priceComparison } = source;\n const flights = itineraryFlights(group, itinerary).map(\n ({ schedule, departureDate, bookingCode }): FlightToBook => ({\n flightNumber: schedule.carrier.marketingFlightNumber,\n airlineCode: schedule.carrier.marketing,\n fromAirportCode: schedule.departure.airport,\n toAirportCode: schedule.arrival.airport,\n departureDate,\n departureTime: schedule.departure.time.slice(0, 5),\n bookingClass: bookingCode,\n flightStatusCode: 'NN',\n }),\n );\n\n const fare = itinerary.pricingInformation[0]?.fare;\n if (fare === undefined) {\n throw new TypeError('sabre-client: el itinerario no trae pricingInformation');\n }\n const passengersPricing = fare.passengerInfoList.map(\n ({ passengerInfo }): PassengerPricing => ({\n passengerCode: passengerInfo.passengerType,\n numberOfpassengers: passengerInfo.passengerNumber ?? 1,\n }),\n );\n\n let priceComparisons: PriceComparison[] | undefined;\n if (priceComparison !== undefined) {\n const total = fare.totalFare?.totalPrice;\n if (total === undefined) {\n throw new TypeError('sabre-client: el itinerario no trae totalFare.totalPrice para priceComparison');\n }\n priceComparisons = [{ desiredAmount: amount(total), ...priceComparison }];\n }\n\n return {\n flights,\n flightPricing: [\n {\n ...(priceComparisons === undefined ? {} : { priceComparisons }),\n qualifiers: {\n passengersPricing,\n ...(fare.validatingCarrierCode === undefined ? {} : { validatingAirlineCode: fare.validatingCarrierCode }),\n },\n },\n ],\n };\n}\n\n/** `1234.5` → `'1234.5'`; el spec acepta hasta 3 decimales. */\nfunction amount(value: number): string {\n return String(Math.round(value * 1000) / 1000);\n}\n","export const VERSION = '0.3.0';\n\nexport { Sabre } from './sabre.js';\nexport type { Air } from './air/air.js';\nexport type {\n BargainFinderMaxRequest,\n BargainFinderMaxResponse,\n RequestOptions,\n} from './air/bargain-finder-max.js';\nexport { buildRevalidateItineraryRequest } from './air/revalidate-itinerary.js';\nexport type {\n RevalidateItineraryRequest,\n RevalidateItineraryRequestSource,\n RevalidateItineraryResponse,\n} from './air/revalidate-itinerary.js';\nexport type {\n LowFareSearchFlight,\n LowFareSearchLocation,\n LowFareSearchOriginDestination,\n LowFareSearchPassengerTypeQuantity,\n LowFareSearchRequestorId,\n LowFareSearchSource,\n LowFareSearchTpaExtensions,\n LowFareSearchTravelerInfoSummary,\n LowFareSearchTravelPreferences,\n OtaAirLowFareSearchRq,\n} from './air/low-fare-search-request.js';\nexport type { SabreTokenStore, StoredToken } from './auth/token-store.js';\nexport type { BookingManagement } from './booking/booking-management.js';\nexport type {\n Booking,\n CreateBookingOptions,\n CreateBookingResponse,\n CreateBookingResponseError,\n} from './booking/create-booking.js';\nexport type {\n BookContactInformation,\n BookGenericSeat,\n BookingAgency,\n BookSeat,\n BookTraveler,\n BrandedFare,\n CreateBookingErrorPolicy,\n CreateBookingRequest,\n FlightDetails,\n FlightStatusCode,\n FlightToBook,\n PassengerPricing,\n PaymentMethod,\n PriceComparison,\n PriceComparisonType,\n PricingDetails,\n PricingQualifiers,\n SeatAreaPreference,\n SpecificFare,\n TicketingPolicy,\n TravelerPhone,\n TravelerTitle,\n} from './booking/create-booking-request.js';\nexport type {\n BookingSource,\n GetBookingExtraFeatures,\n GetBookingOptions,\n GetBookingRequest,\n GetBookingResponse,\n GetBookingReturnOnly,\n} from './booking/get-booking.js';\nexport type {\n BookingItemReference,\n CancelBookingErrorPolicy,\n CancelBookingNotification,\n CancelBookingOptions,\n CancelBookingRequest,\n CancelBookingResponse,\n CancelSegmentReference,\n FlightTicketOperation,\n RefundDocumentsType,\n} from './booking/cancel-booking.js';\nexport type { BookingResponseError } from './booking/booking-errors.js';\nexport { buildBookingFlightDetails } from './booking/flight-details.js';\nexport type { BookingFlightDetailsSource } from './booking/flight-details.js';\nexport type {\n SabreAuthVersion,\n SabreConfig,\n SabreConfigV2,\n SabreConfigV3,\n SabreCredentials,\n SabreCredentialsV2,\n SabreEnvironment,\n} from './config.js';\nexport type { RetryOptions } from './http/retry.js';\nexport * from './errors/index.js';\nexport * from './logging/index.js';\nexport type {\n BaggageAllowanceDesc,\n BaggageInformation,\n CurrencyConversion,\n Fare,\n FareComponent,\n FareComponentDesc,\n FareComponentDescSegment,\n FareComponentSegment,\n FareComponentSegmentDetail,\n FareMessage,\n GroupedItineraryResponse,\n Itinerary,\n ItineraryGroup,\n ItineraryMessage,\n Leg,\n LegDesc,\n LegSchedule,\n LegScheduleRef,\n LegDescription,\n ObFeeDesc,\n PassengerInfo,\n PassengerTotalFare,\n PricingInformation,\n Ref,\n ScheduleCarrier,\n ScheduleDesc,\n ScheduleEndpoint,\n ScheduleEquipment,\n TaxDesc,\n TaxSummaryDesc,\n TotalFare,\n ValidatingCarrierDesc,\n} from './air/grouped-itinerary.js';\n"],"mappings":"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","names":["PATH","isObject","PATH","isObject","PATH","isObject","warningOf","PATH","isObject","errorOf","warningOf","isObject"]}
package/package.json CHANGED
@@ -1,57 +1,39 @@
1
1
  {
2
2
  "name": "sabre-client",
3
- "version": "0.2.4",
4
- "description": "Sabre Node.js SDK",
5
- "keywords": [
6
- "sabre",
7
- "client",
8
- "devStudio",
9
- "rest"
10
- ],
11
- "homepage": "https://github.com/CarlosIvanSoto/sabre#readme",
12
- "bugs": {
13
- "url": "https://github.com/CarlosIvanSoto/sabre/issues"
14
- },
3
+ "version": "0.3.0-next.0",
4
+ "description": "TypeScript SDK for the Sabre GDS APIs: managed OAuth, air shopping, itinerary revalidation and booking over REST, built on Web Standard APIs to run on any server runtime.",
5
+ "license": "MIT",
15
6
  "repository": {
16
7
  "type": "git",
17
8
  "url": "git+https://github.com/CarlosIvanSoto/sabre.git"
18
9
  },
19
- "license": "MIT",
20
- "author": "Carlos Ivan Soto <csoto_99@outlook.com>",
21
10
  "type": "module",
22
- "main": "./dist/index.cjs",
23
- "module": "./dist/index.js",
24
- "types": "./dist/index.d.ts",
25
- "files": [
26
- "dist/**"
27
- ],
28
11
  "exports": {
29
12
  ".": {
30
- "import": "./dist/index.js",
31
- "require": "./dist/index.cjs"
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
32
15
  }
33
16
  },
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "sideEffects": false,
23
+ "engines": {
24
+ "node": ">=22.12"
25
+ },
34
26
  "scripts": {
35
27
  "build": "tsup",
36
- "prepublishOnly": "npm run build",
37
- "test": "jest --passWithNoTests",
38
- "test:watch": "jest --watch",
39
- "lint": "eslint . --ext .ts --report-unused-disable-directives --max-warnings 0",
40
- "type-check": "tsc --noEmit",
41
- "example:auth-atk": "node --env-file=.env --import=tsx examples/auth-atk.ts",
42
- "example:search-shop": "node --env-file=.env --import=tsx examples/search-shop.ts"
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
31
+ "check:portable": "node scripts/check-portable.mjs src"
43
32
  },
44
33
  "devDependencies": {
45
- "@eslint/js": "^9.38.0",
46
- "@types/jest": "^30.0.0",
47
- "@types/node": "^24.8.1",
48
- "eslint": "^9.38.0",
49
- "jest": "^30.2.0",
50
- "ts-jest": "^29.4.5",
51
- "ts-node": "^10.9.2",
52
- "tsup": "^8.5.0",
53
- "tsx": "^4.20.6",
54
- "typescript": "^5.9.3",
55
- "typescript-eslint": "^8.46.1"
34
+ "tsup": "^8.5.1",
35
+ "typescript": "~5.9.3",
36
+ "vite": "^7.3.7",
37
+ "vitest": "^5.0.3"
56
38
  }
57
39
  }