sabre-client 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -59,6 +59,22 @@ var SabreBusinessError = class extends SabreError {
59
59
  this.errors = options.errors ?? [];
60
60
  }
61
61
  };
62
+ var SabreUncertainOutcomeError = class extends SabreError {
63
+ name = "SabreUncertainOutcomeError";
64
+ operation;
65
+ confirmationId;
66
+ reason;
67
+ tickets;
68
+ warnings;
69
+ constructor(message, options) {
70
+ super(message, { ...options, retryable: false });
71
+ this.operation = options.operation;
72
+ this.confirmationId = options.confirmationId;
73
+ this.reason = options.reason;
74
+ this.tickets = options.tickets ?? [];
75
+ this.warnings = options.warnings ?? [];
76
+ }
77
+ };
62
78
  var SabreWarning = class extends SabreError {
63
79
  name = "SabreWarning";
64
80
  service;
@@ -200,10 +216,10 @@ function classifyItineraryMessages(body, service, catalog) {
200
216
  const error = messages.find((message) => message.severity?.toLowerCase() === "error");
201
217
  if (error === void 0) return void 0;
202
218
  const match = findInCatalog(messages, catalog);
203
- const text = match?.text ?? (typeof error.text === "string" ? error.text : "");
219
+ const text2 = match?.text ?? (typeof error.text === "string" ? error.text : "");
204
220
  const known = match?.entry;
205
- const code = known?.code ?? error.code ?? text;
206
- return new SabreBusinessError(`${service}: ${text || code}`, {
221
+ const code = known?.code ?? error.code ?? text2;
222
+ return new SabreBusinessError(`${service}: ${text2 || code}`, {
207
223
  service,
208
224
  code,
209
225
  retryable: known?.retryable ?? false,
@@ -213,8 +229,8 @@ function classifyItineraryMessages(body, service, catalog) {
213
229
  function findInCatalog(messages, catalog) {
214
230
  for (const message of messages) {
215
231
  if (typeof message.text !== "string") continue;
216
- const text = message.text.toLowerCase();
217
- const entry = catalog.find((candidate) => text.includes(candidate.code.toLowerCase()));
232
+ const text2 = message.text.toLowerCase();
233
+ const entry = catalog.find((candidate) => text2.includes(candidate.code.toLowerCase()));
218
234
  if (entry !== void 0) return { entry, text: message.text };
219
235
  }
220
236
  return void 0;
@@ -623,9 +639,9 @@ function buildTokenRequestV2(credentials) {
623
639
  function buildTokenRequest(authVersion, credentials) {
624
640
  return authVersion === "v3" ? buildTokenRequestV3(credentials) : buildTokenRequestV2(credentials);
625
641
  }
626
- function base64(text) {
642
+ function base64(text2) {
627
643
  let binary = "";
628
- for (const byte of new TextEncoder().encode(text)) binary += String.fromCharCode(byte);
644
+ for (const byte of new TextEncoder().encode(text2)) binary += String.fromCharCode(byte);
629
645
  return btoa(binary);
630
646
  }
631
647
 
@@ -798,25 +814,217 @@ var AuthManager = class {
798
814
  }
799
815
  };
800
816
 
817
+ // src/tickets/fulfill-tickets.ts
818
+ var FULFILL_TICKETS_SERVICE = "fulfillFlightTickets";
819
+ var FULFILL_TICKETS_OPERATION = "tickets.fulfill";
820
+ var PATH3 = "/v1/trip/orders/fulfillFlightTickets";
821
+ var NO_NEW_TICKETS = /no new tickets have been issued/i;
822
+ var GATEWAY_5XX = /* @__PURE__ */ new Set([500, 502, 503, 504]);
823
+ function validateFulfillTicketsRequest(request, options) {
824
+ const fail8 = (message) => {
825
+ throw new TypeError(`sabre-client: tickets.fulfill ${message}`);
826
+ };
827
+ if (!isObject2(request) || !nonEmpty(request.confirmationId)) fail8("espera { confirmationId: string, fulfillments: [...] }");
828
+ if (!Array.isArray(request.fulfillments) || request.fulfillments.length === 0 || request.fulfillments.length > 99) {
829
+ fail8("necesita fulfillments con 1 a 99 elementos");
830
+ }
831
+ for (const [index, fulfillment] of request.fulfillments.entries()) {
832
+ const qualifiers = isObject2(fulfillment) ? fulfillment.ticketingQualifiers : void 0;
833
+ if (qualifiers?.commissionAmount !== void 0 && qualifiers.commissionPercentage !== void 0) {
834
+ fail8(`no combina commissionAmount con commissionPercentage (fulfillments[${index}])`);
835
+ }
836
+ }
837
+ const printers = request.designatePrinters ?? [];
838
+ if (printers.length > 1 && printers.some((printer) => printer.profileNumber !== void 0)) {
839
+ fail8("manda un perfil de impresoras solo, en un \xFAnico elemento de designatePrinters");
840
+ }
841
+ const retries = options.retry?.maxRetries;
842
+ if (retries !== void 0 && retries !== 0) fail8("no se reintenta nunca: retry.maxRetries solo puede ser 0");
843
+ }
844
+ async function fulfillTickets(transport, request, options = {}) {
845
+ validateFulfillTicketsRequest(request, options);
846
+ const { confirmationId } = request;
847
+ const body = { acceptPriceChanges: false, priceQuoteExpirationMethod: "Quit", ...request };
848
+ let sent = false;
849
+ const userOnRawRequest = options.onRawRequest;
850
+ const hooks = rawHooks(
851
+ {
852
+ onRawResponse: options.onRawResponse,
853
+ // `onRawRequest` llega si algún intento llamó a `fetch`: así se sabe si el request salió.
854
+ onRawRequest: (raw) => {
855
+ sent = true;
856
+ userOnRawRequest?.(raw);
857
+ }
858
+ },
859
+ FULFILL_TICKETS_OPERATION
860
+ );
861
+ let response;
862
+ try {
863
+ response = await transport.request({
864
+ method: "POST",
865
+ path: PATH3,
866
+ service: FULFILL_TICKETS_SERVICE,
867
+ idempotent: false,
868
+ retry: { maxRetries: 0 },
869
+ body,
870
+ classify: (parsed) => classifyFulfillTickets(parsed, confirmationId),
871
+ ...options.signal === void 0 ? {} : { signal: options.signal },
872
+ ...hooks
873
+ });
874
+ } catch (error) {
875
+ throw uncertainInFlight(error, sent, confirmationId, FULFILL_TICKETS_OPERATION, FULFILL_TICKETS_SERVICE);
876
+ }
877
+ return toFulfillTicketsResponse(response, confirmationId);
878
+ }
879
+ function uncertainInFlight(error, sent, confirmationId, operation, service) {
880
+ if (error instanceof SabreUncertainOutcomeError) return error;
881
+ const make = (reason, detail) => new SabreUncertainOutcomeError(`${service}: no se sabe si se hizo (${detail}). Verifica antes de reintentar.`, {
882
+ operation,
883
+ confirmationId,
884
+ reason,
885
+ cause: error
886
+ });
887
+ if (error instanceof Error && error.name === "AbortError") return sent ? make("ABORTED", "abort con el request ya mandado") : error;
888
+ if (error instanceof SabreGatewayError && error.protocol === "rest") {
889
+ if (error.status === void 0) return make("TRANSPORT", "fallo de red sin respuesta");
890
+ if (GATEWAY_5XX.has(error.status)) return make("GATEWAY_5XX", `HTTP ${error.status} del gateway`);
891
+ }
892
+ return error;
893
+ }
894
+ function classifyFulfillTickets(body, confirmationId) {
895
+ if (!isObject2(body)) {
896
+ return uncertain("UNPARSEABLE", "respuesta 2xx sin un objeto JSON", { confirmationId, raw: body });
897
+ }
898
+ const response = body;
899
+ const items = allItems(response);
900
+ const warnings = items.filter(isWarning).map((item) => toWarning(FULFILL_TICKETS_SERVICE, item));
901
+ const fatal = items.filter((item) => !isWarning(item));
902
+ const tickets = ticketsOf(response);
903
+ const reported = tickets.map(uncertainTicket);
904
+ const context = { confirmationId, tickets: reported, warnings, raw: body };
905
+ const has = (type) => items.find((item) => item.type === type);
906
+ const retrieve = has("UNABLE_TO_RETRIEVE_TICKETS");
907
+ if (retrieve) return uncertain("UNABLE_TO_RETRIEVE_TICKETS", describe(retrieve), context);
908
+ const notConfirmed = has("FULFILLMENT_NOT_CONFIRMED");
909
+ if (notConfirmed) return uncertain("FULFILLMENT_NOT_CONFIRMED", describe(notConfirmed), context);
910
+ const timeout = fatal.find((item) => item.type === "INTERNAL_SERVER_TIMEOUT" && !NO_NEW_TICKETS.test(item.description ?? ""));
911
+ if (timeout) return uncertain("INTERNAL_SERVER_TIMEOUT", describe(timeout), context);
912
+ const downline = fatal.find((item) => item.type === "DOWNLINE_SERVICE_ERROR");
913
+ if (downline) return uncertain("DOWNLINE_SERVICE_ERROR", describe(downline), context);
914
+ const card = fatal.find((item) => item.type === "PAYMENT_CARD_ISSUE");
915
+ if (card) return uncertain("PAYMENT_CARD_ISSUE", describe(card), context);
916
+ const notCommitted = tickets.filter((ticket) => ticket.isCommitted === false);
917
+ if (notCommitted.length > 0) {
918
+ return uncertain("NOT_COMMITTED", `${notCommitted.length} boleto(s) emitido(s) sin guardar en el PNR (ghost ticket)`, context);
919
+ }
920
+ if (tickets.length > 0) return void 0;
921
+ const [first, ...rest] = fatal;
922
+ if (first !== void 0) {
923
+ return toBusinessError(FULFILL_TICKETS_SERVICE, first, { warnings, errors: rest.map((item) => toBusinessError(FULFILL_TICKETS_SERVICE, item)) });
924
+ }
925
+ return uncertain("FULFILLMENT_NOT_CONFIRMED", "respuesta 2xx sin boletos ni errores", context);
926
+ }
927
+ function toFulfillTicketsResponse(response, confirmationId) {
928
+ const items = allItems(response);
929
+ const warnings = items.filter(isWarning).map((item) => toWarning(FULFILL_TICKETS_SERVICE, item));
930
+ const errors = items.filter((item) => !isWarning(item)).map((item) => toBusinessError(FULFILL_TICKETS_SERVICE, item));
931
+ const partial = errors.length > 0 || warnings.some((warning) => warning.code === "PARTIAL_FULFILLMENT");
932
+ return {
933
+ status: partial ? "partial" : "issued",
934
+ confirmationId,
935
+ tickets: ticketsOf(response),
936
+ warnings,
937
+ errors,
938
+ ...response.timestamp === void 0 ? {} : { timestamp: response.timestamp },
939
+ ...response.request === void 0 ? {} : { request: response.request }
940
+ };
941
+ }
942
+ function allItems(response) {
943
+ return [...responseErrors(response), ...Array.isArray(response.warnings) ? responseErrors({ errors: response.warnings }) : []];
944
+ }
945
+ function ticketsOf(response) {
946
+ return Array.isArray(response.tickets) ? response.tickets.filter((ticket) => isObject2(ticket) && nonEmpty(ticket.number)) : [];
947
+ }
948
+ function uncertainTicket(ticket) {
949
+ return {
950
+ number: ticket.number,
951
+ ...ticket.ticketStatusCode === void 0 ? {} : { ticketStatusCode: ticket.ticketStatusCode },
952
+ ...ticket.isCommitted === void 0 ? {} : { isCommitted: ticket.isCommitted }
953
+ };
954
+ }
955
+ function uncertain(reason, detail, context) {
956
+ return new SabreUncertainOutcomeError(`${FULFILL_TICKETS_SERVICE}: no se sabe si emiti\xF3 (${reason}: ${detail}). Verifica con tickets.verify antes de reintentar.`, {
957
+ operation: FULFILL_TICKETS_OPERATION,
958
+ ...context,
959
+ reason
960
+ });
961
+ }
962
+ function describe(item) {
963
+ return nonEmpty(item.description) ? item.description : item.type;
964
+ }
965
+
801
966
  // src/booking/cancel-booking.ts
802
967
  var CANCEL_BOOKING_SERVICE = "cancelBooking";
803
- var PATH3 = "/v1/trip/orders/cancelBooking";
968
+ var CANCEL_BOOKING_OPERATION = "booking.cancel";
969
+ var END_TRANSACTION_PROBLEM = "END_TRANSACTION_PROBLEM";
970
+ var PATH4 = "/v1/trip/orders/cancelBooking";
804
971
  var NO_ITEMS_CANCELLED = "NO_ITEMS_CANCELLED";
805
972
  var ITEM_LISTS = ["flights", "hotels", "cars", "trains", "cruises", "segments"];
806
973
  async function cancelBooking(transport, request, options = {}) {
807
974
  validateCancelBookingRequest(request);
808
- const body = await transport.request({
809
- method: "POST",
810
- path: PATH3,
811
- service: CANCEL_BOOKING_SERVICE,
812
- idempotent: false,
813
- body: request,
814
- classify: classifyCancelBooking,
815
- ...options.signal === void 0 ? {} : { signal: options.signal },
816
- ...rawHooks(options, "booking.cancel")
817
- });
975
+ const voiding = request.flightTicketOperation === "VOID";
976
+ let sent = false;
977
+ const hooks = voiding ? rawHooks(
978
+ {
979
+ onRawResponse: options.onRawResponse,
980
+ // `onRawRequest` llega si algún intento llamó a `fetch`: así se sabe si el void salió.
981
+ onRawRequest: (raw) => {
982
+ sent = true;
983
+ options.onRawRequest?.(raw);
984
+ }
985
+ },
986
+ CANCEL_BOOKING_OPERATION
987
+ ) : rawHooks(options, CANCEL_BOOKING_OPERATION);
988
+ let body;
989
+ try {
990
+ body = await transport.request({
991
+ method: "POST",
992
+ path: PATH4,
993
+ service: CANCEL_BOOKING_SERVICE,
994
+ idempotent: false,
995
+ body: request,
996
+ classify: voiding ? (parsed) => classifyVoid(parsed, request.confirmationId) : classifyCancelBooking,
997
+ ...options.signal === void 0 ? {} : { signal: options.signal },
998
+ ...hooks
999
+ });
1000
+ } catch (error) {
1001
+ if (!voiding) throw error;
1002
+ throw uncertainInFlight(error, sent, request.confirmationId, CANCEL_BOOKING_OPERATION, CANCEL_BOOKING_SERVICE);
1003
+ }
818
1004
  return toCancelBookingResponse(body);
819
1005
  }
1006
+ function classifyVoid(body, confirmationId) {
1007
+ const voidUncertain = (reason, detail, warnings = []) => new SabreUncertainOutcomeError(`${CANCEL_BOOKING_SERVICE}: no se sabe si el void se hizo (${reason}: ${detail}). Verifica con tickets.verify o booking.get antes de reintentar.`, {
1008
+ operation: CANCEL_BOOKING_OPERATION,
1009
+ confirmationId,
1010
+ reason,
1011
+ tickets: isObject2(body) ? voidedOf(body).map((number) => ({ number })) : [],
1012
+ warnings,
1013
+ raw: body
1014
+ });
1015
+ if (!isObject2(body)) return voidUncertain("UNPARSEABLE", "respuesta 2xx sin un objeto JSON");
1016
+ const failure = classifyCancelBooking(body);
1017
+ if (failure !== void 0) return failure;
1018
+ const items = responseErrors(body);
1019
+ const pending = items.find((item) => item.type === END_TRANSACTION_PROBLEM);
1020
+ if (pending !== void 0) {
1021
+ return voidUncertain("END_TRANSACTION_PROBLEM", pending.description ?? "Confirmation is pending", items.filter(isWarning).map(warningOf));
1022
+ }
1023
+ return void 0;
1024
+ }
1025
+ function voidedOf(body) {
1026
+ return Array.isArray(body.voidedTickets) ? body.voidedTickets.filter(nonEmpty) : [];
1027
+ }
820
1028
  function validateCancelBookingRequest(request) {
821
1029
  if (!isObject2(request) || !nonEmpty(request.confirmationId)) {
822
1030
  throw new TypeError("sabre-client: booking.cancel espera { confirmationId: string, ... }");
@@ -975,7 +1183,7 @@ function amount(value) {
975
1183
 
976
1184
  // src/booking/create-booking.ts
977
1185
  var CREATE_BOOKING_SERVICE = "createBooking";
978
- var PATH4 = "/v1/trip/orders/createBooking";
1186
+ var PATH5 = "/v1/trip/orders/createBooking";
979
1187
  var UNABLE_TO_RETRIEVE_BOOKING = "UNABLE_TO_RETRIEVE_BOOKING";
980
1188
  async function createBooking(transport, request, options = {}) {
981
1189
  validateCreateBookingRequest(request);
@@ -984,7 +1192,7 @@ async function createBooking(transport, request, options = {}) {
984
1192
  }
985
1193
  const body = await transport.request({
986
1194
  method: "POST",
987
- path: PATH4,
1195
+ path: PATH5,
988
1196
  service: CREATE_BOOKING_SERVICE,
989
1197
  idempotent: false,
990
1198
  body: request,
@@ -1068,7 +1276,7 @@ function warningOf2(item) {
1068
1276
 
1069
1277
  // src/booking/get-booking.ts
1070
1278
  var GET_BOOKING_SERVICE = "getBooking";
1071
- var PATH5 = "/v1/trip/orders/getBooking";
1279
+ var PATH6 = "/v1/trip/orders/getBooking";
1072
1280
  var RETRYABLE_TYPES = /* @__PURE__ */ new Set(["INTERNAL_SERVER_TIMEOUT", "DOWNLINE_SERVICE_FAILURE"]);
1073
1281
  async function getBooking(transport, request, options = {}) {
1074
1282
  if (!isObject2(request) || !nonEmpty(request.confirmationId)) {
@@ -1076,7 +1284,7 @@ async function getBooking(transport, request, options = {}) {
1076
1284
  }
1077
1285
  const body = await transport.request({
1078
1286
  method: "POST",
1079
- path: PATH5,
1287
+ path: PATH6,
1080
1288
  service: GET_BOOKING_SERVICE,
1081
1289
  idempotent: true,
1082
1290
  body: request,
@@ -1160,6 +1368,15 @@ var BookingManagement = class {
1160
1368
  * Nunca se reintenta automáticamente. Lanza `SabreBusinessError` si algo falló o si Sabre
1161
1369
  * responde `NO_ITEMS_CANCELLED` (no se canceló nada), aunque llegue como aviso. Con
1162
1370
  * `END_TRANSACTION_PROBLEM` en `warnings`, la confirmación quedó pendiente: verifica con `get`.
1371
+ *
1372
+ * **Void** (`flightTicketOperation: 'VOID'`, ADR-031): anula los boletos y es **irreversible**.
1373
+ * Con `cancelAll` y `HALT_ON_ERROR`, una sola llamada anula y cancela la reserva; `voidedTickets`
1374
+ * trae los números anulados (CERT, 2026-11-13). Un fallo de red, un 5xx, un cuerpo ilegible, un
1375
+ * abort con el request ya mandado o `END_TRANSACTION_PROBLEM` lanzan `SabreUncertainOutcomeError`:
1376
+ * no se sabe si se anuló. Verifica con `sabre.tickets.verify` (un boleto anulado queda en `TV`) o
1377
+ * con `get` antes de reintentar. `VOID` sobre una reserva sin boletos lanza `NO_ITEMS_CANCELLED`
1378
+ * con `UNABLE_TO_VOID_TICKET` y **no cancela nada**: para una reserva sin emitir, cancela sin
1379
+ * `VOID`.
1163
1380
  */
1164
1381
  cancel(request, options) {
1165
1382
  return cancelBooking(this.#transport, request, options);
@@ -1409,7 +1626,7 @@ var RestTransport = class {
1409
1626
  });
1410
1627
  } catch (cause) {
1411
1628
  if (isAbort(cause, request.signal)) throw cause;
1412
- const error = new SabreGatewayError(`${request.service}: fallo de red (${describe(cause)})`, {
1629
+ const error = new SabreGatewayError(`${request.service}: fallo de red (${describe2(cause)})`, {
1413
1630
  protocol: "rest",
1414
1631
  retryable: true,
1415
1632
  cause
@@ -1417,9 +1634,9 @@ var RestTransport = class {
1417
1634
  this.#log.emit("error", "sabre.request.end", { ...logContext, durationMs: Date.now() - startedAt, error });
1418
1635
  throw error;
1419
1636
  }
1420
- const text = await response.text();
1421
- if (capture !== void 0) capture.last = { status: response.status, headers: response.headers, body: text };
1422
- const parsed = parseBody(text);
1637
+ const text2 = await response.text();
1638
+ if (capture !== void 0) capture.last = { status: response.status, headers: response.headers, body: text2 };
1639
+ const parsed = parseBody(text2);
1423
1640
  const endContext = { ...logContext, status: response.status, durationMs: Date.now() - startedAt };
1424
1641
  if (!response.ok) {
1425
1642
  const error = gatewayError(request.service, response.status, parsed);
@@ -1443,12 +1660,12 @@ var RestTransport = class {
1443
1660
  return url.toString();
1444
1661
  }
1445
1662
  };
1446
- function parseBody(text) {
1447
- if (text === "") return void 0;
1663
+ function parseBody(text2) {
1664
+ if (text2 === "") return void 0;
1448
1665
  try {
1449
- return JSON.parse(text);
1666
+ return JSON.parse(text2);
1450
1667
  } catch {
1451
- return text;
1668
+ return text2;
1452
1669
  }
1453
1670
  }
1454
1671
  function gatewayError(service, status, body) {
@@ -1490,10 +1707,93 @@ function isUnauthorized(error) {
1490
1707
  function isAbort(error, signal) {
1491
1708
  return signal?.aborted === true || error instanceof Error && error.name === "AbortError";
1492
1709
  }
1493
- function describe(error) {
1710
+ function describe2(error) {
1494
1711
  return error instanceof Error ? error.message : String(error);
1495
1712
  }
1496
1713
 
1714
+ // src/tickets/verify-tickets.ts
1715
+ var LIVE_STATUS = /* @__PURE__ */ new Set(["TE", "ME", "TO"]);
1716
+ async function verifyTickets(transport, request, options = {}, now = () => /* @__PURE__ */ new Date()) {
1717
+ if (!isObject2(request) || !nonEmpty(request.confirmationId)) {
1718
+ throw new TypeError("sabre-client: tickets.verify espera { confirmationId: string, ... }");
1719
+ }
1720
+ for (const key of ["knownTickets", "expectedTickets"]) {
1721
+ const list = request[key];
1722
+ if (list !== void 0 && (!Array.isArray(list) || !list.every(nonEmpty))) {
1723
+ throw new TypeError(`sabre-client: tickets.verify espera ${key} como lista de n\xFAmeros de boleto`);
1724
+ }
1725
+ }
1726
+ const booking = await getBooking(
1727
+ transport,
1728
+ { confirmationId: request.confirmationId, ...request.targetPcc === void 0 ? {} : { targetPcc: request.targetPcc } },
1729
+ options
1730
+ );
1731
+ const checkedAt = now().toISOString();
1732
+ const known = new Set(request.knownTickets ?? []);
1733
+ const live = (booking.flightTickets ?? []).filter(isLive).map(toVerified);
1734
+ const fresh = live.filter((ticket) => !known.has(ticket.number));
1735
+ const expected = request.expectedTickets ?? [];
1736
+ const missing = expected.filter((number) => !live.some((ticket) => ticket.number === number));
1737
+ if (missing.length > 0) return { status: "notCommitted", tickets: fresh, missing, checkedAt };
1738
+ if (fresh.length > 0 || expected.length > 0) return { status: "issued", tickets: fresh, checkedAt };
1739
+ return { status: "notFound", checkedAt };
1740
+ }
1741
+ function isLive(ticket) {
1742
+ return isObject2(ticket) && nonEmpty(ticket.number) && ticket.ticketStatusCode !== void 0 && LIVE_STATUS.has(ticket.ticketStatusCode);
1743
+ }
1744
+ function toVerified(ticket) {
1745
+ return {
1746
+ number: ticket.number,
1747
+ ...ticket.ticketStatusCode === void 0 ? {} : { ticketStatusCode: ticket.ticketStatusCode },
1748
+ ...ticket.ticketStatusName === void 0 ? {} : { ticketStatusName: ticket.ticketStatusName },
1749
+ ...ticket.date === void 0 ? {} : { date: ticket.date },
1750
+ ...ticket.ticketingPcc === void 0 ? {} : { ticketingPcc: ticket.ticketingPcc }
1751
+ };
1752
+ }
1753
+
1754
+ // src/tickets/tickets-management.ts
1755
+ var TicketsManagement = class {
1756
+ #transport;
1757
+ /** @internal Lo construye el cliente `Sabre`. */
1758
+ constructor(transport) {
1759
+ this.#transport = transport;
1760
+ }
1761
+ /**
1762
+ * Fulfill Flight Tickets: emite los boletos (y EMD) de una reserva con su PQ guardado. **Mueve
1763
+ * dinero y nunca se reintenta**, ni ante un fallo de transporte ni ante un error que Sabre marque
1764
+ * como temporal (ADR-031). Pasar `retry.maxRetries` distinto de 0 lanza `TypeError` sin red.
1765
+ *
1766
+ * El SDK manda `acceptPriceChanges: false` y `priceQuoteExpirationMethod: 'Quit'` salvo que se
1767
+ * pasen otros valores: una emisión automática no paga un precio que nadie vio.
1768
+ *
1769
+ * Desenlaces:
1770
+ * - **Emitido** (`status: 'issued'`): todos los boletos con `isCommitted: true`.
1771
+ * - **Parcial** (`status: 'partial'`): hay boletos emitidos y algo faltó (`PARTIAL_FULFILLMENT`
1772
+ * o un error junto con boletos). **No es una emisión completa**: hay pasajeros sin boleto.
1773
+ * Guarda los emitidos y verifica antes de completar.
1774
+ * - **No emitido**: lanza `SabreBusinessError` (p. ej. `PRICE_MISMATCH`, `BOOKING_FULFILLED`) o
1775
+ * `SabreGatewayError` (400, 401, 403, 429).
1776
+ * - **Incierto**: lanza `SabreUncertainOutcomeError`. Verifica con `verify`, pasando sus
1777
+ * `tickets` como `expectedTickets`, antes de pensar en reintentar.
1778
+ *
1779
+ * `BOOKING_FULFILLED` quiere decir que la reserva ya tiene boletos, **no** que sean de esta
1780
+ * emisión: verifica con `verify`. Los errores de configuración del PCC (comisión, impresora,
1781
+ * Secure Flight) llegan como `DOWNLINE_SERVICE_ERROR` y hoy se tratan como incierto (CERT,
1782
+ * 2026-11-12).
1783
+ */
1784
+ fulfill(request, options) {
1785
+ return fulfillTickets(this.#transport, request, options);
1786
+ }
1787
+ /**
1788
+ * ¿Se emitió? Lee la reserva con Get Booking y devuelve `issued`, `notCommitted` o `notFound`,
1789
+ * por el `ticketStatusCode` de cada boleto. Nunca emite. Un `notFound` no prueba que no se haya
1790
+ * emitido: ver `VerifyTicketsResponse`.
1791
+ */
1792
+ verify(request, options) {
1793
+ return verifyTickets(this.#transport, request, options);
1794
+ }
1795
+ };
1796
+
1497
1797
  // src/sabre.ts
1498
1798
  var Sabre = class {
1499
1799
  #config;
@@ -1502,6 +1802,8 @@ var Sabre = class {
1502
1802
  air;
1503
1803
  /** Booking Management: creación de reservas. */
1504
1804
  booking;
1805
+ /** Emisión de boletos (Fulfill Flight Tickets) y su verificación. Mueve dinero: ver ADR-031. */
1806
+ tickets;
1505
1807
  constructor(config) {
1506
1808
  this.#config = resolveConfig(config);
1507
1809
  this.#transport = new RestTransport(this.#config);
@@ -1509,6 +1811,7 @@ var Sabre = class {
1509
1811
  this.#transport.setAuthorizationProvider(auth.bearerProvider());
1510
1812
  this.air = new Air(this.#transport);
1511
1813
  this.booking = new BookingManagement(this.#transport);
1814
+ this.tickets = new TicketsManagement(this.#transport);
1512
1815
  }
1513
1816
  get environment() {
1514
1817
  return this.#config.environment;
@@ -1635,7 +1938,7 @@ var SoapTransport = class {
1635
1938
  });
1636
1939
  } catch (cause) {
1637
1940
  if (isAbort2(cause, request.signal)) throw cause;
1638
- const error = new SabreGatewayError(`${request.service}: fallo de red (${describe2(cause)})`, {
1941
+ const error = new SabreGatewayError(`${request.service}: fallo de red (${describe3(cause)})`, {
1639
1942
  protocol: "soap",
1640
1943
  retryable: false,
1641
1944
  cause
@@ -1644,9 +1947,9 @@ var SoapTransport = class {
1644
1947
  throw error;
1645
1948
  }
1646
1949
  const original = await response.text();
1647
- const text = redactSoapEnvelope(scrubToken(original, request.security));
1648
- capture.last = { status: response.status, headers: response.headers, body: text };
1649
- const document = parseEnvelope(text);
1950
+ const text2 = redactSoapEnvelope(scrubToken(original, request.security));
1951
+ capture.last = { status: response.status, headers: response.headers, body: text2 };
1952
+ const document = parseEnvelope(text2);
1650
1953
  const messageId = stringAt(document?.Header, "MessageHeader", "MessageData", "MessageId");
1651
1954
  const endContext = {
1652
1955
  ...logContext,
@@ -1655,13 +1958,13 @@ var SoapTransport = class {
1655
1958
  ...messageId === void 0 ? {} : { messageId }
1656
1959
  };
1657
1960
  try {
1658
- const result = this.#classify(request, response, document, text);
1961
+ const result = this.#classify(request, response, document, text2);
1659
1962
  this.#log.emit("info", "sabre.request.end", { ...endContext, warnings: result.warnings.length });
1660
1963
  return {
1661
1964
  ...result,
1662
1965
  messageId,
1663
- respondedAt: respondedAtOf(text),
1664
- raw: text,
1966
+ respondedAt: respondedAtOf(text2),
1967
+ raw: text2,
1665
1968
  securityToken: request.readSecurityToken === true ? readSecurityToken(original) : void 0,
1666
1969
  status: response.status
1667
1970
  };
@@ -1672,18 +1975,18 @@ var SoapTransport = class {
1672
1975
  }
1673
1976
  }
1674
1977
  /** Orden de detección: fault (gateway), luego `stl:Error` (negocio), luego data. */
1675
- #classify(request, response, document, text) {
1978
+ #classify(request, response, document, text2) {
1676
1979
  const { service } = request;
1677
1980
  if (document === void 0) {
1678
1981
  throw new SabreGatewayError(`${service}: HTTP ${response.status}, la respuesta no es un sobre SOAP`, {
1679
1982
  protocol: "soap",
1680
1983
  status: response.status,
1681
1984
  retryable: false,
1682
- raw: text
1985
+ raw: text2
1683
1986
  });
1684
1987
  }
1685
1988
  const fault = asNode(document.Body.Fault);
1686
- if (fault !== void 0) throw faultError(service, response.status, fault, text);
1989
+ if (fault !== void 0) throw faultError(service, response.status, fault, text2);
1687
1990
  const [payloadName, payloadValue] = firstElement(document.Body);
1688
1991
  const payload = asNode(payloadValue);
1689
1992
  if (payloadName === void 0 || payload === void 0) {
@@ -1691,7 +1994,7 @@ var SoapTransport = class {
1691
1994
  protocol: "soap",
1692
1995
  status: response.status,
1693
1996
  retryable: false,
1694
- raw: text
1997
+ raw: text2
1695
1998
  });
1696
1999
  }
1697
2000
  if (!response.ok) {
@@ -1699,20 +2002,20 @@ var SoapTransport = class {
1699
2002
  protocol: "soap",
1700
2003
  status: response.status,
1701
2004
  retryable: false,
1702
- raw: text
2005
+ raw: text2
1703
2006
  });
1704
2007
  }
1705
2008
  const results = asNode(payload.ApplicationResults);
1706
- const warnings = asArray(results?.Warning).map((node3) => {
1707
- const entry = resultEntry(node3);
1708
- return new SabreWarning(`${service}: ${entry.description}`, { service, code: entry.code, raw: text });
2009
+ const warnings = asArray(results?.Warning).map((node4) => {
2010
+ const entry = resultEntry(node4);
2011
+ return new SabreWarning(`${service}: ${entry.description}`, { service, code: entry.code, raw: text2 });
1709
2012
  });
1710
- const errors = asArray(results?.Error).map((node3) => {
1711
- const entry = resultEntry(node3);
2013
+ const errors = asArray(results?.Error).map((node4) => {
2014
+ const entry = resultEntry(node4);
1712
2015
  return new SabreBusinessError(`${service}: ${entry.description}`, {
1713
2016
  service,
1714
2017
  code: entry.code,
1715
- raw: text,
2018
+ raw: text2,
1716
2019
  retryable: PREVIOUS_ENTRY_ACTIVE.test(entry.description)
1717
2020
  });
1718
2021
  });
@@ -1721,7 +2024,7 @@ var SoapTransport = class {
1721
2024
  throw new SabreBusinessError(first.message, {
1722
2025
  service,
1723
2026
  code: first.code,
1724
- raw: text,
2027
+ raw: text2,
1725
2028
  retryable: first.retryable,
1726
2029
  warnings,
1727
2030
  errors: rest
@@ -1818,16 +2121,16 @@ function securityHeader(security) {
1818
2121
  function wantsRawRequest(request) {
1819
2122
  return request.onRawRequest !== void 0 && "binarySecurityToken" in request.security;
1820
2123
  }
1821
- function scrubToken(text, security) {
1822
- if (!("binarySecurityToken" in security) || security.binarySecurityToken === "") return text;
2124
+ function scrubToken(text2, security) {
2125
+ if (!("binarySecurityToken" in security) || security.binarySecurityToken === "") return text2;
1823
2126
  const token = security.binarySecurityToken;
1824
- return text.split(token).join(REDACTED).split(xmlEscape(token)).join(REDACTED);
2127
+ return text2.split(token).join(REDACTED).split(xmlEscape(token)).join(REDACTED);
1825
2128
  }
1826
- function parseEnvelope(text, xmlParser = parser) {
1827
- if (text.trim() === "") return void 0;
2129
+ function parseEnvelope(text2, xmlParser = parser) {
2130
+ if (text2.trim() === "") return void 0;
1828
2131
  let parsed;
1829
2132
  try {
1830
- parsed = xmlParser.parse(text);
2133
+ parsed = xmlParser.parse(text2);
1831
2134
  } catch {
1832
2135
  return void 0;
1833
2136
  }
@@ -1842,7 +2145,7 @@ function readSecurityToken(original) {
1842
2145
  return token === void 0 || token.trim() === "" ? void 0 : token.trim();
1843
2146
  }
1844
2147
  var USG_CODE = /\bUSG_[A-Z0-9_]+\b/;
1845
- function faultError(service, status, fault, text) {
2148
+ function faultError(service, status, fault, text2) {
1846
2149
  const faultcode = textOf(fault.faultcode);
1847
2150
  const faultstring = textOf(fault.faultstring);
1848
2151
  const haystack = [faultcode, faultstring, JSON.stringify(fault.detail ?? "")].join(" ");
@@ -1853,12 +2156,12 @@ function faultError(service, status, fault, text) {
1853
2156
  protocol: "soap",
1854
2157
  status,
1855
2158
  retryable,
1856
- raw: text,
2159
+ raw: text2,
1857
2160
  ...code === void 0 || code === "" ? {} : { code }
1858
2161
  });
1859
2162
  }
1860
- function resultEntry(node3) {
1861
- const entry = asNode(node3) ?? {};
2163
+ function resultEntry(node4) {
2164
+ const entry = asNode(node4) ?? {};
1862
2165
  const messages = [];
1863
2166
  const shortTexts = [];
1864
2167
  let code;
@@ -1896,8 +2199,8 @@ function untrimmedPayload(raw) {
1896
2199
  const document = parseEnvelope(raw, untrimmedParser);
1897
2200
  return document === void 0 ? void 0 : asNode(firstElement(document.Body)[1]);
1898
2201
  }
1899
- function firstElement(node3) {
1900
- for (const [key, value] of Object.entries(node3)) {
2202
+ function firstElement(node4) {
2203
+ for (const [key, value] of Object.entries(node4)) {
1901
2204
  if (!key.startsWith("@") && key !== "#text") return [key, Array.isArray(value) ? value[0] : value];
1902
2205
  }
1903
2206
  return [void 0, void 0];
@@ -1912,14 +2215,14 @@ function asArray(value) {
1912
2215
  }
1913
2216
  function textOf(value) {
1914
2217
  if (typeof value === "string") return value;
1915
- const node3 = asNode(value);
1916
- const text = node3?.["#text"];
1917
- return typeof text === "string" ? text : node3 === void 0 ? void 0 : "";
2218
+ const node4 = asNode(value);
2219
+ const text2 = node4?.["#text"];
2220
+ return typeof text2 === "string" ? text2 : node4 === void 0 ? void 0 : "";
1918
2221
  }
1919
2222
  function stringAt(root2, ...path) {
1920
- let node3 = root2;
1921
- for (const key of path) node3 = asNode(node3)?.[key];
1922
- return nonEmpty2(textOf(node3));
2223
+ let node4 = root2;
2224
+ for (const key of path) node4 = asNode(node4)?.[key];
2225
+ return nonEmpty2(textOf(node4));
1923
2226
  }
1924
2227
  function nonEmpty2(value) {
1925
2228
  return typeof value === "string" && value !== "" ? value : void 0;
@@ -1927,7 +2230,7 @@ function nonEmpty2(value) {
1927
2230
  function isAbort2(error, signal) {
1928
2231
  return signal?.aborted === true || error instanceof Error && error.name === "AbortError";
1929
2232
  }
1930
- function describe2(error) {
2233
+ function describe3(error) {
1931
2234
  return error instanceof Error ? error.message : String(error);
1932
2235
  }
1933
2236
 
@@ -2026,9 +2329,9 @@ function isMessageQueue(queue) {
2026
2329
  return queue === MESSAGE_QUEUE;
2027
2330
  }
2028
2331
  function toQueueRef(value) {
2029
- const text = value?.trim();
2030
- if (text === void 0 || text === "") return void 0;
2031
- return /^\d+$/.test(text) ? Number(text) : text;
2332
+ const text2 = value?.trim();
2333
+ if (text2 === void 0 || text2 === "") return void 0;
2334
+ return /^\d+$/.test(text2) ? Number(text2) : text2;
2032
2335
  }
2033
2336
 
2034
2337
  // src/queue/queue-access.ts
@@ -2074,12 +2377,12 @@ function node(value) {
2074
2377
  return typeof value === "object" && value !== null ? value : void 0;
2075
2378
  }
2076
2379
  function attribute(value, name) {
2077
- const text = node(value)?.[`@${name}`];
2078
- return typeof text === "string" && text.trim() !== "" ? text.trim() : void 0;
2380
+ const text2 = node(value)?.[`@${name}`];
2381
+ return typeof text2 === "string" && text2.trim() !== "" ? text2.trim() : void 0;
2079
2382
  }
2080
2383
  function element(value) {
2081
- const text = textOf(Array.isArray(value) ? value[0] : value)?.trim();
2082
- return text === void 0 || text === "" ? void 0 : text;
2384
+ const text2 = textOf(Array.isArray(value) ? value[0] : value)?.trim();
2385
+ return text2 === void 0 || text2 === "" ? void 0 : text2;
2083
2386
  }
2084
2387
  function textLines(raw, payloadName) {
2085
2388
  let parsed;
@@ -2095,16 +2398,16 @@ function textLines(raw, payloadName) {
2095
2398
  function paragraphLines(raw) {
2096
2399
  return textLines(raw, "QueueAccessRS");
2097
2400
  }
2098
- function isEndOfDisplay(text) {
2099
- return text?.trim() === END_OF_DISPLAY;
2401
+ function isEndOfDisplay(text2) {
2402
+ return text2?.trim() === END_OF_DISPLAY;
2100
2403
  }
2101
2404
  function isEndOfDisplayResult(error) {
2102
2405
  return resultHasText(error, END_OF_DISPLAY);
2103
2406
  }
2104
- function resultHasText(error, text) {
2407
+ function resultHasText(error, text2) {
2105
2408
  const prefix = `${error.service}: `;
2106
2409
  const description = error.message.startsWith(prefix) ? error.message.slice(prefix.length) : error.message;
2107
- return description.split(/ \/ | \(|\)/).some((part) => part.trim() === text);
2410
+ return description.split(/ \/ | \(|\)/).some((part) => part.trim() === text2);
2108
2411
  }
2109
2412
  function queueEndError(error, service) {
2110
2413
  if (!(error instanceof SabreBusinessError) || error.service !== service) return void 0;
@@ -2185,8 +2488,8 @@ function parseHostCount(value) {
2185
2488
  const match = /^[.\s]*(\d+)\s*$/.exec(value ?? "");
2186
2489
  return match === null ? void 0 : Number(match[1]);
2187
2490
  }
2188
- function attribute2(node3, name) {
2189
- const value = node3?.[`@${name}`];
2491
+ function attribute2(node4, name) {
2492
+ const value = node4?.[`@${name}`];
2190
2493
  return typeof value === "string" ? value : void 0;
2191
2494
  }
2192
2495
  function parseQueueCountResponse(response) {
@@ -2249,8 +2552,8 @@ function malformed(detail, response) {
2249
2552
  });
2250
2553
  }
2251
2554
  function nonEmpty3(value) {
2252
- const text = value?.trim();
2253
- return text === void 0 || text === "" ? void 0 : text;
2555
+ const text2 = value?.trim();
2556
+ return text2 === void 0 || text2 === "" ? void 0 : text2;
2254
2557
  }
2255
2558
 
2256
2559
  // src/queue/queue-list.ts
@@ -2321,13 +2624,13 @@ function queueActivityRequest(pcc, options, target = {}) {
2321
2624
  ...options
2322
2625
  };
2323
2626
  }
2324
- function attribute3(node3, name) {
2325
- const value = (Array.isArray(node3) ? node3[0] : node3)?.[`@${name}`];
2627
+ function attribute3(node4, name) {
2628
+ const value = (Array.isArray(node4) ? node4[0] : node4)?.[`@${name}`];
2326
2629
  return typeof value === "string" ? value : void 0;
2327
2630
  }
2328
2631
  function nonEmpty4(value) {
2329
- const text = value?.trim();
2330
- return text === void 0 || text === "" ? void 0 : text;
2632
+ const text2 = value?.trim();
2633
+ return text2 === void 0 || text2 === "" ? void 0 : text2;
2331
2634
  }
2332
2635
  function parseQueueActivityResponse(response) {
2333
2636
  const queues = [];
@@ -2352,10 +2655,10 @@ function parseQueueActivityResponse(response) {
2352
2655
  ...respondedAtField(response.raw)
2353
2656
  };
2354
2657
  }
2355
- function counters(node3, label, response) {
2658
+ function counters(node4, label, response) {
2356
2659
  const result = {};
2357
2660
  for (const [element2, key] of COUNTERS) {
2358
- const raw = attribute3(node3[element2], "Count");
2661
+ const raw = attribute3(node4[element2], "Count");
2359
2662
  const count = parseHostCount(raw);
2360
2663
  if (count === void 0) throw malformed2(`${label} con ${element2} Count="${raw ?? ""}"`, response);
2361
2664
  result[key] = count;
@@ -2409,13 +2712,13 @@ function signatureLocator(lines) {
2409
2712
  }
2410
2713
  return void 0;
2411
2714
  }
2412
- function isEnd(response, text) {
2413
- return response.warnings.some(isEndOfDisplayResult) || isEndOfDisplay(text.find((line) => line.trim() !== ""));
2715
+ function isEnd(response, text2) {
2716
+ return response.warnings.some(isEndOfDisplayResult) || isEndOfDisplay(text2.find((line) => line.trim() !== ""));
2414
2717
  }
2415
2718
  function parsePlaceStep(response) {
2416
- const text = textLines(response.raw, "QueuePlaceRS");
2417
- if (isEnd(response, text)) return endStep(response.warnings, "end-of-display", response.raw);
2418
- const locator = signatureLocator(text);
2719
+ const text2 = textLines(response.raw, "QueuePlaceRS");
2720
+ if (isEnd(response, text2)) return endStep(response.warnings, "end-of-display", response.raw);
2721
+ const locator = signatureLocator(text2);
2419
2722
  if (locator === void 0) {
2420
2723
  throw new SabreGatewayError(`${QUEUE_PLACE_SERVICE}: respuesta no reconocida (sin l\xEDnea de firma del PNR ni fin de cola)`, {
2421
2724
  protocol: "soap",
@@ -2424,11 +2727,11 @@ function parsePlaceStep(response) {
2424
2727
  raw: response.raw
2425
2728
  });
2426
2729
  }
2427
- return { done: false, kind: "pnr", item: { locator, paragraph: text }, warnings: response.warnings, ...respondedAtField(response.raw) };
2730
+ return { done: false, kind: "pnr", item: { locator, paragraph: text2 }, warnings: response.warnings, ...respondedAtField(response.raw) };
2428
2731
  }
2429
2732
  function parsePlaceUnknown(response) {
2430
- const text = textLines(response.raw, "QueuePlaceRS");
2431
- if (isEnd(response, text) || signatureLocator(text) !== void 0) return parsePlaceStep(response);
2733
+ const text2 = textLines(response.raw, "QueuePlaceRS");
2734
+ if (isEnd(response, text2) || signatureLocator(text2) !== void 0) return parsePlaceStep(response);
2432
2735
  return parsePlaceResult(response);
2433
2736
  }
2434
2737
  function parsePlaceResult(response) {
@@ -2812,15 +3115,248 @@ function validateSelection(selection) {
2812
3115
  });
2813
3116
  }
2814
3117
 
3118
+ // src/reporting/daily-sales-summary.ts
3119
+ var DAILY_SALES_SUMMARY_SERVICE = "dailySalesSummary";
3120
+ var NAMESPACE6 = "http://www.sabre.com/ns/Ticketing/AsrServices/1.0";
3121
+ var CLIENT_TIMEOUT_SECS = 25;
3122
+ var PCC2 = /^[A-Z0-9]{3,4}$/;
3123
+ var DATE = /^\d{4}-\d{2}-\d{2}$/;
3124
+ var DOCUMENT_TYPES = ["TKT", "EMD", "RFND", "RFEMD", "MCO"];
3125
+ var SETTLEMENT_TYPES = ["TAT", "TCH", "TKT", "NDC"];
3126
+ function validateDailySalesSummaryRequest(request) {
3127
+ const fail8 = (detail) => {
3128
+ throw new TypeError(`sabre-client: reporting.dailySalesSummary: ${detail}`);
3129
+ };
3130
+ if (request.pcc !== void 0 && !PCC2.test(request.pcc)) fail8("pcc debe tener 3 o 4 letras may\xFAsculas o d\xEDgitos");
3131
+ if (request.date !== void 0 && (!DATE.test(request.date) || Number.isNaN(Date.parse(`${request.date}T00:00:00Z`)))) {
3132
+ fail8("date debe tener la forma 'YYYY-MM-DD'");
3133
+ }
3134
+ if (request.documentType !== void 0 && !DOCUMENT_TYPES.includes(request.documentType)) fail8(`documentType debe ser ${DOCUMENT_TYPES.join(", ")}`);
3135
+ if (request.settlementType !== void 0 && !SETTLEMENT_TYPES.includes(request.settlementType)) fail8(`settlementType debe ser ${SETTLEMENT_TYPES.join(", ")}`);
3136
+ if (request.airline !== void 0) {
3137
+ const { code, number } = request.airline;
3138
+ if (code === void 0 && number === void 0) fail8("airline necesita code o number");
3139
+ if (code !== void 0 && !/^[A-Z0-9]{2}$/.test(code)) fail8("airline.code debe tener 2 caracteres");
3140
+ if (number !== void 0 && !/^\d{3}$/.test(number)) fail8("airline.number debe tener 3 d\xEDgitos");
3141
+ }
3142
+ if (request.documentNumber !== void 0 && !/^\d{10,15}$/.test(request.documentNumber)) fail8("documentNumber debe tener de 10 a 15 d\xEDgitos");
3143
+ }
3144
+ function dailySalesSummaryPayload(request = {}) {
3145
+ const { pcc, date, documentType, settlementType, airline, documentNumber } = request;
3146
+ const airlineXml = airline === void 0 ? "" : `<Airline>${airline.code === void 0 ? "" : `<AirlineCode>${xmlEscape(airline.code)}</AirlineCode>`}${airline.number === void 0 ? "" : `<AirlineNumber>${xmlEscape(airline.number)}</AirlineNumber>`}</Airline>`;
3147
+ const criteria = [
3148
+ pcc === void 0 ? "" : `<PseudoCityCode>${xmlEscape(pcc)}</PseudoCityCode>`,
3149
+ airlineXml,
3150
+ date === void 0 ? "" : `<ReportDate>${xmlEscape(date)}</ReportDate>`,
3151
+ settlementType === void 0 ? "" : `<SettlementType>${xmlEscape(settlementType)}</SettlementType>`,
3152
+ documentType === void 0 ? "" : `<DocumentType>${xmlEscape(documentType)}</DocumentType>`,
3153
+ documentNumber === void 0 ? "" : `<DocumentNumber>${xmlEscape(documentNumber)}</DocumentNumber>`
3154
+ ].join("");
3155
+ return `<DailySalesSummaryRQ xmlns="${NAMESPACE6}" version="1.2.2"><Header/><SelectionCriteria isCacheLateLargeReports="false" clientTimeoutSecs="${CLIENT_TIMEOUT_SECS}">${criteria}</SelectionCriteria></DailySalesSummaryRQ>`;
3156
+ }
3157
+ function dailySalesSummaryRequest(request, options) {
3158
+ return {
3159
+ service: DAILY_SALES_SUMMARY_SERVICE,
3160
+ action: "TKT_TravelAgencyReportsRQ",
3161
+ payload: dailySalesSummaryPayload(request),
3162
+ idempotent: true,
3163
+ operation: "reporting.dailySalesSummary",
3164
+ ...options
3165
+ };
3166
+ }
3167
+ var node2 = (value) => {
3168
+ const first = Array.isArray(value) ? value[0] : value;
3169
+ return typeof first === "object" && first !== null ? first : void 0;
3170
+ };
3171
+ var attribute4 = (value, name) => {
3172
+ const found = node2(value)?.[`@${name}`];
3173
+ return typeof found === "string" ? found : void 0;
3174
+ };
3175
+ var text = (value) => {
3176
+ const found = textOf(Array.isArray(value) ? value[0] : value)?.trim();
3177
+ return found === void 0 || found === "" ? void 0 : found;
3178
+ };
3179
+ var flag = (value) => value === "true" ? true : value === "false" ? false : void 0;
3180
+ var integer = (value) => value !== void 0 && /^\d+$/.test(value) ? Number(value) : void 0;
3181
+ function defined(entries) {
3182
+ return Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== void 0));
3183
+ }
3184
+ function summaryErrors(payload) {
3185
+ const results = [node2(payload.Header)?.Results, payload.Results];
3186
+ return results.flatMap(
3187
+ (value) => asArray(node2(value)?.Error).map((error) => {
3188
+ const entry = node2(error);
3189
+ const message = text(entry?.Message) ?? text(entry?.Description) ?? text(error) ?? "";
3190
+ const code = text(entry?.ErrorCode) ?? text(entry?.Code) ?? attribute4(error, "code") ?? attribute4(entry?.Message, "code") ?? /^\s*(\d{4,6})\b/.exec(message)?.[1] ?? "UNKNOWN";
3191
+ const status = attribute4(error, "status");
3192
+ return defined({ status, code, message });
3193
+ })
3194
+ );
3195
+ }
3196
+ function failedDocumentsOf(message) {
3197
+ const list = message.slice(message.indexOf(":") + 1);
3198
+ return [...list.matchAll(/\d{7,}/g)].map((match) => match[0]);
3199
+ }
3200
+ function readTransaction(value, response) {
3201
+ const transaction2 = node2(value) ?? {};
3202
+ const details = node2(transaction2.DocumentDetails) ?? {};
3203
+ const documentType = text(transaction2.DocumentType);
3204
+ const documentNumber = text(details.DocumentNumber);
3205
+ const transactionCode = text(details.TransactionCode);
3206
+ const transactionDateTime = text(transaction2.TransactionDateTime);
3207
+ if (documentType === void 0 || documentNumber === void 0 || transactionCode === void 0 || transactionDateTime === void 0) {
3208
+ throw malformed3("Transaction sin DocumentType, DocumentNumber, TransactionCode o TransactionDateTime", response);
3209
+ }
3210
+ const airline = transaction2.AirlineCode;
3211
+ const commission = node2(transaction2.Commission);
3212
+ const payments = node2(transaction2.Payments);
3213
+ const documentPayment = node2(payments?.DocumentPayment);
3214
+ return defined({
3215
+ documentType,
3216
+ transactionCode,
3217
+ documentStatusCode: text(details.DocumentStatusCode),
3218
+ settlementType: text(transaction2.SettlementType) ?? "",
3219
+ pnrLocator: text(transaction2.PnrLocator),
3220
+ passengerName: text(transaction2.PassengerName),
3221
+ documentNumber,
3222
+ lastConjunctiveDocumentNumber: text(details.LastConjunctiveDocumentNumber),
3223
+ stockType: text(details.StockType),
3224
+ airline: defined({ code: text(airline) ?? "", number: attribute4(airline, "AirlineNumber") }),
3225
+ commission: commission === void 0 ? void 0 : defined({ amount: text(commission.Amount), percent: text(commission.Percent) }),
3226
+ payments: payments === void 0 ? void 0 : {
3227
+ currencyCode: text(payments.CurrencyCode) ?? "",
3228
+ total: text(documentPayment?.PaymentTotal) ?? "",
3229
+ details: asArray(documentPayment?.PaymentDetail).map(
3230
+ (detail) => defined({
3231
+ fop: attribute4(detail, "fop") ?? "",
3232
+ category: attribute4(detail, "category") ?? "",
3233
+ cardType: attribute4(detail, "cardType"),
3234
+ amount: text(node2(detail)?.PaymentAmount) ?? ""
3235
+ })
3236
+ )
3237
+ },
3238
+ agentSine: text(transaction2.AgentSine) ?? "",
3239
+ agentPseudoCity: text(transaction2.AgentPseudoCity),
3240
+ transactionDateTime,
3241
+ electronicDocument: flag(attribute4(value, "electronicDocument")),
3242
+ nonInteractive: flag(attribute4(value, "nonInteractive")),
3243
+ itineraryType: attribute4(value, "itineraryType"),
3244
+ automatedRefund: flag(attribute4(value, "automatedRefund"))
3245
+ });
3246
+ }
3247
+ function readTotals(report) {
3248
+ const amountOf = (value) => {
3249
+ const amount2 = text(value);
3250
+ return amount2 === void 0 ? void 0 : defined({ amount: amount2, count: integer(attribute4(value, "count")) });
3251
+ };
3252
+ return asArray(report?.TotalDailySales).flatMap((total) => {
3253
+ const transactionType = text(node2(total)?.TransactionType) ?? "";
3254
+ return asArray(node2(total)?.SalesBySettlement).flatMap((settlement) => {
3255
+ const settlementType = text(node2(settlement)?.SettlementType) ?? "";
3256
+ return asArray(node2(settlement)?.SaleTotals).map((totals) => {
3257
+ const sale = node2(totals);
3258
+ return defined({
3259
+ transactionType,
3260
+ settlementType,
3261
+ currencyCode: text(sale?.CurrencyCode),
3262
+ cash: amountOf(sale?.CashTotals),
3263
+ credit: amountOf(sale?.CreditTotals),
3264
+ commission: amountOf(sale?.CommissionTotals)
3265
+ });
3266
+ });
3267
+ });
3268
+ });
3269
+ }
3270
+ function parseDailySalesSummaryResponse(response, fallbackPcc) {
3271
+ const payload = response.payload;
3272
+ const errors = summaryErrors(payload);
3273
+ const fatal = errors.filter((error) => error.status?.toLowerCase() !== "incomplete");
3274
+ const [first, ...rest] = fatal;
3275
+ if (first !== void 0) {
3276
+ throw new SabreBusinessError(`${DAILY_SALES_SUMMARY_SERVICE}: ${first.code} ${first.message}`.trim(), {
3277
+ service: DAILY_SALES_SUMMARY_SERVICE,
3278
+ code: first.code,
3279
+ raw: response.raw,
3280
+ errors: rest.map(
3281
+ (error) => new SabreBusinessError(`${DAILY_SALES_SUMMARY_SERVICE}: ${error.code} ${error.message}`.trim(), { service: DAILY_SALES_SUMMARY_SERVICE, code: error.code, raw: response.raw })
3282
+ )
3283
+ });
3284
+ }
3285
+ const incomplete = errors.filter((error) => error.status?.toLowerCase() === "incomplete");
3286
+ const header = node2(payload.DSHeader);
3287
+ const report = node2(payload.DailySalesReport);
3288
+ const reportId = attribute4(payload, "reportId");
3289
+ const queryStillRunning = attribute4(payload, "isQueryStillRunning") === "true";
3290
+ const deferred = reportId !== void 0 || queryStillRunning;
3291
+ return defined({
3292
+ status: deferred ? "deferred" : incomplete.length > 0 ? "incomplete" : "complete",
3293
+ pcc: text(header?.PseudoCityCode) ?? fallbackPcc,
3294
+ agencyName: text(header?.AgencyName),
3295
+ reportDate: text(report?.ReportDate) ?? text(header?.ReportDate),
3296
+ transactions: asArray(report?.Transaction).map((transaction2) => readTransaction(transaction2, response)),
3297
+ totals: readTotals(report),
3298
+ failedDocuments: incomplete.length > 0 ? incomplete.flatMap((error) => failedDocumentsOf(error.message)) : void 0,
3299
+ deferred: deferred ? defined({
3300
+ reportId,
3301
+ chunkNumber: integer(attribute4(payload, "chunkNumber")),
3302
+ maxChunks: integer(attribute4(payload, "maxChunks")),
3303
+ queryStillRunning
3304
+ }) : void 0,
3305
+ respondedAt: respondedAtField(response.raw).respondedAt
3306
+ });
3307
+ }
3308
+ function malformed3(detail, response) {
3309
+ return new SabreGatewayError(`${DAILY_SALES_SUMMARY_SERVICE}: respuesta no reconocida (${detail})`, {
3310
+ protocol: "soap",
3311
+ retryable: false,
3312
+ raw: response.raw
3313
+ });
3314
+ }
3315
+
3316
+ // src/reporting/session-reporting.ts
3317
+ var SessionReporting = class {
3318
+ #context;
3319
+ /** @internal Lo construye `SabreSession`. */
3320
+ constructor(context) {
3321
+ this.#context = context;
3322
+ }
3323
+ /**
3324
+ * Ventas del día: el «Summary» del DQB (`TKT_TravelAgencyReportsRQ` / `DailySalesSummaryRQ`
3325
+ * 1.2.2). Una transacción por movimiento del PCC en el día: ventas, reembolsos, voids, EMD y MCO,
3326
+ * sin tope. Sin `date`, da el día en curso, hasta minutos antes de la llamada (producción,
3327
+ * 2026-11-12). **Trae datos del pasajero** (`passengerName`).
3328
+ *
3329
+ * - Las fechas y horas (`transactionDateTime`, `reportDate`) llegan **tal como vienen, sin zona**.
3330
+ * En producción vienen en hora local del PCC; el SDK no las convierte.
3331
+ * - Solo `status: 'complete'` es el día entero. `incomplete` trae `failedDocuments`, y `deferred`
3332
+ * quiere decir que Sabre lo dejó en caché o sigue corriendo: hay que volver a pedirlo. El SDK
3333
+ * no pide `CachedReportRQ`.
3334
+ * - Los importes van como string.
3335
+ *
3336
+ * Otro PCC necesita Branch Access: sin él, Sabre responde `45100` y el SDK lanza
3337
+ * `SabreBusinessError` (`service: 'dailySalesSummary'`, `code: '45100'`). Lo mismo con `21212`
3338
+ * (versión) y cualquier otro error de la respuesta. Un fallo de autorización del gateway
3339
+ * (`USG_AUTHORIZATION_FAILED`) sale como los demás de la sesión. Un filtro con forma
3340
+ * equivocada lanza `TypeError` sin red.
3341
+ *
3342
+ * Es una lectura: se reintenta ante fallos de transporte, pero no ante errores de negocio.
3343
+ */
3344
+ async dailySalesSummary(request = {}, options = {}) {
3345
+ validateDailySalesSummaryRequest(request);
3346
+ const response = await this.#context.send(dailySalesSummaryRequest(request, options));
3347
+ return parseDailySalesSummaryResponse(response, request.pcc ?? this.#context.pcc);
3348
+ }
3349
+ };
3350
+
2815
3351
  // src/reservation/reservation-history.ts
2816
3352
  var RESERVATION_HISTORY_SERVICE = "itineraryHistory";
2817
- var NAMESPACE6 = "http://webservices.sabre.com/sabreXML/2011/10";
3353
+ var NAMESPACE7 = "http://webservices.sabre.com/sabreXML/2011/10";
2818
3354
  var LOCATOR = /^[A-Z0-9]{6}$/;
2819
3355
  function isRecordLocator(value) {
2820
3356
  return typeof value === "string" && LOCATOR.test(value);
2821
3357
  }
2822
3358
  function reservationHistoryPayload(locator) {
2823
- return `<TravelItineraryHistoryRQ Version="2.4.0" xmlns="${NAMESPACE6}"><UniqueID ID="${xmlEscape(locator)}"/></TravelItineraryHistoryRQ>`;
3359
+ return `<TravelItineraryHistoryRQ Version="2.4.0" xmlns="${NAMESPACE7}"><UniqueID ID="${xmlEscape(locator)}"/></TravelItineraryHistoryRQ>`;
2824
3360
  }
2825
3361
  function reservationHistoryRequest(locator, options) {
2826
3362
  return {
@@ -2832,76 +3368,76 @@ function reservationHistoryRequest(locator, options) {
2832
3368
  ...options
2833
3369
  };
2834
3370
  }
2835
- function node2(value) {
3371
+ function node3(value) {
2836
3372
  const first = Array.isArray(value) ? value[0] : value;
2837
3373
  return typeof first === "object" && first !== null ? first : void 0;
2838
3374
  }
2839
- function attribute4(value, name) {
2840
- const text = node2(value)?.[`@${name}`];
2841
- if (typeof text !== "string") return void 0;
2842
- const trimmed = text.trim();
3375
+ function attribute5(value, name) {
3376
+ const text2 = node3(value)?.[`@${name}`];
3377
+ if (typeof text2 !== "string") return void 0;
3378
+ const trimmed = text2.trim();
2843
3379
  return trimmed === "" ? void 0 : trimmed;
2844
3380
  }
2845
- function defined(fields) {
3381
+ function defined2(fields) {
2846
3382
  return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== void 0));
2847
3383
  }
2848
- function integer(value) {
3384
+ function integer2(value) {
2849
3385
  return value !== void 0 && /^\d+$/.test(value) ? Number(value) : void 0;
2850
3386
  }
2851
3387
  function parseReservationHistoryResponse(response) {
2852
- const transactions = asArray(response.payload.HistoricalInfo).map((info) => transaction(node2(info) ?? {}, response));
3388
+ const transactions = asArray(response.payload.HistoricalInfo).map((info) => transaction(node3(info) ?? {}, response));
2853
3389
  return { transactions, warnings: response.warnings, ...respondedAtField(response.raw) };
2854
3390
  }
2855
3391
  function transaction(info, response) {
2856
- const source = node2(node2(info.ItineraryRef)?.Source);
2857
- const flightSegments = asArray(node2(node2(info.ItineraryInfo)?.ReservationItems)?.Item).flatMap(
2858
- (item) => asArray(node2(item)?.FlightSegment).map((segment) => flightSegment(node2(segment) ?? {}, response))
3392
+ const source = node3(node3(info.ItineraryRef)?.Source);
3393
+ const flightSegments = asArray(node3(node3(info.ItineraryInfo)?.ReservationItems)?.Item).flatMap(
3394
+ (item) => asArray(node3(item)?.FlightSegment).map((segment) => flightSegment(node3(segment) ?? {}, response))
2859
3395
  );
2860
3396
  return {
2861
- ...defined({
2862
- rph: integer(attribute4(info, "RPH")),
2863
- createdAt: attribute4(source, "CreateDateTime"),
2864
- agent: attribute4(source, "CreationAgent"),
2865
- agentDutyCode: attribute4(source, "CreationAgentDutyCode"),
2866
- agentFunctionCode: attribute4(source, "CreationAgentFunctionCode"),
2867
- pcc: attribute4(source, "PseudoCityCode"),
2868
- aaaPcc: attribute4(source, "AAA_PseudoCityCode") ?? attribute4(source, "AAAPseudoCityCode"),
2869
- receivedFrom: attribute4(source, "ReceivedFrom")
3397
+ ...defined2({
3398
+ rph: integer2(attribute5(info, "RPH")),
3399
+ createdAt: attribute5(source, "CreateDateTime"),
3400
+ agent: attribute5(source, "CreationAgent"),
3401
+ agentDutyCode: attribute5(source, "CreationAgentDutyCode"),
3402
+ agentFunctionCode: attribute5(source, "CreationAgentFunctionCode"),
3403
+ pcc: attribute5(source, "PseudoCityCode"),
3404
+ aaaPcc: attribute5(source, "AAA_PseudoCityCode") ?? attribute5(source, "AAAPseudoCityCode"),
3405
+ receivedFrom: attribute5(source, "ReceivedFrom")
2870
3406
  }),
2871
3407
  flightSegments,
2872
3408
  generalInfo: asArray(info.GeneralInfo).map((entry) => textEntry(entry, "GeneralInfo", response)),
2873
- remarks: asArray(node2(info.RemarkInfo)?.Remark).map((entry) => textEntry(entry, "Remark", response)),
3409
+ remarks: asArray(node3(info.RemarkInfo)?.Remark).map((entry) => textEntry(entry, "Remark", response)),
2874
3410
  accounting: asArray(info.AccountingInfo).map(
2875
- (entry) => defined({ action: attribute4(entry, "Action"), type: attribute4(entry, "Type"), linkCode: attribute4(entry, "LinkCode") })
3411
+ (entry) => defined2({ action: attribute5(entry, "Action"), type: attribute5(entry, "Type"), linkCode: attribute5(entry, "LinkCode") })
2876
3412
  )
2877
3413
  };
2878
3414
  }
2879
3415
  function textEntry(entry, label, response) {
2880
- const action = attribute4(entry, "Action");
2881
- if (action === void 0) throw malformed3(`${label} sin Action`, response);
2882
- const texts = asArray(node2(entry)?.Text).map((text) => textOf(text) ?? "");
3416
+ const action = attribute5(entry, "Action");
3417
+ if (action === void 0) throw malformed4(`${label} sin Action`, response);
3418
+ const texts = asArray(node3(entry)?.Text).map((text2) => textOf(text2) ?? "");
2883
3419
  return { action, text: texts.join("\n") };
2884
3420
  }
2885
3421
  function flightSegment(segment, response) {
2886
- const action = attribute4(segment, "Action");
2887
- if (action === void 0) throw malformed3("FlightSegment sin Action", response);
3422
+ const action = attribute5(segment, "Action");
3423
+ if (action === void 0) throw malformed4("FlightSegment sin Action", response);
2888
3424
  return {
2889
3425
  action,
2890
- ...defined({
2891
- status: attribute4(segment, "Status"),
2892
- marketingAirline: attribute4(segment.MarketingAirline, "Code"),
2893
- flightNumber: attribute4(segment, "FlightNumber") ?? attribute4(segment.MarketingAirline, "FlightNumber"),
2894
- bookingClass: attribute4(segment, "ResBookDesigCode"),
2895
- origin: attribute4(segment.OriginLocation, "LocationCode"),
2896
- destination: attribute4(segment.DestinationLocation, "LocationCode"),
2897
- departureDateTime: attribute4(segment, "DepartureDateTime"),
2898
- arrivalDateTime: attribute4(segment, "ArrivalDateTime"),
2899
- numberInParty: integer(attribute4(segment, "NumberInParty")),
2900
- supplierRef: attribute4(segment.SupplierRef, "ID")
3426
+ ...defined2({
3427
+ status: attribute5(segment, "Status"),
3428
+ marketingAirline: attribute5(segment.MarketingAirline, "Code"),
3429
+ flightNumber: attribute5(segment, "FlightNumber") ?? attribute5(segment.MarketingAirline, "FlightNumber"),
3430
+ bookingClass: attribute5(segment, "ResBookDesigCode"),
3431
+ origin: attribute5(segment.OriginLocation, "LocationCode"),
3432
+ destination: attribute5(segment.DestinationLocation, "LocationCode"),
3433
+ departureDateTime: attribute5(segment, "DepartureDateTime"),
3434
+ arrivalDateTime: attribute5(segment, "ArrivalDateTime"),
3435
+ numberInParty: integer2(attribute5(segment, "NumberInParty")),
3436
+ supplierRef: attribute5(segment.SupplierRef, "ID")
2901
3437
  })
2902
3438
  };
2903
3439
  }
2904
- function malformed3(detail, response) {
3440
+ function malformed4(detail, response) {
2905
3441
  return new SabreGatewayError(`${RESERVATION_HISTORY_SERVICE}: respuesta no reconocida (${detail})`, {
2906
3442
  protocol: "soap",
2907
3443
  status: response.status,
@@ -2948,14 +3484,14 @@ var SessionReservation = class {
2948
3484
 
2949
3485
  // src/session/command.ts
2950
3486
  var SABRE_COMMAND_SERVICE = "sabreCommand";
2951
- var NAMESPACE7 = "http://webservices.sabre.com/sabreXML/2011/10";
3487
+ var NAMESPACE8 = "http://webservices.sabre.com/sabreXML/2011/10";
2952
3488
  var MAX_COMMAND_LENGTH = 1023;
2953
3489
  var DOUBLE_WIDTH = /* @__PURE__ */ new Set(["!", "%", "$", "&", "\xA5", "\xA7"]);
2954
3490
  function fail5(message) {
2955
3491
  throw new TypeError(`sabre-client: ${message}`);
2956
3492
  }
2957
3493
  function sabreCommandPayload(command) {
2958
- return `<SabreCommandLLSRQ xmlns="${NAMESPACE7}" Version="2.0.0" ReturnHostCommand="true"><Request Output="SCREEN"><HostCommand>${xmlEscape(command)}</HostCommand></Request></SabreCommandLLSRQ>`;
3494
+ return `<SabreCommandLLSRQ xmlns="${NAMESPACE8}" Version="2.0.0" ReturnHostCommand="true"><Request Output="SCREEN"><HostCommand>${xmlEscape(command)}</HostCommand></Request></SabreCommandLLSRQ>`;
2959
3495
  }
2960
3496
  function commandToken(command) {
2961
3497
  return (command.trim().split(/[¥‡\s]/u)[0] ?? "").slice(0, 4);
@@ -3034,6 +3570,8 @@ var SabreSession = class {
3034
3570
  queue;
3035
3571
  /** La reserva: el historial de un PNR, dentro de esta sesión. */
3036
3572
  reservation;
3573
+ /** Reportes del PCC: las ventas del día (`dailySalesSummary`), dentro de esta sesión. */
3574
+ reporting;
3037
3575
  #transport;
3038
3576
  #pcc;
3039
3577
  #conversationId;
@@ -3062,6 +3600,7 @@ var SabreSession = class {
3062
3600
  log: internal.transport.log
3063
3601
  });
3064
3602
  this.reservation = new SessionReservation({ send: (request) => this[sessionSend](request) });
3603
+ this.reporting = new SessionReporting({ send: (request) => this[sessionSend](request), pcc: internal.pcc });
3065
3604
  if (internal.keepAlive) this.#scheduleKeepAlive(KEEP_ALIVE_IDLE_MS);
3066
3605
  }
3067
3606
  /**
@@ -3226,8 +3765,8 @@ function checkPingResponse(response) {
3226
3765
  const error = asArray(errors?.Error)[0];
3227
3766
  if (error !== void 0) {
3228
3767
  const type = error["@Type"];
3229
- const text = textOf(error)?.trim();
3230
- throw new SabreGatewayError(`ping: OTA_PingRS con error${text ? `: ${text}` : ""}`, {
3768
+ const text2 = textOf(error)?.trim();
3769
+ throw new SabreGatewayError(`ping: OTA_PingRS con error${text2 ? `: ${text2}` : ""}`, {
3231
3770
  protocol: "soap",
3232
3771
  status: response.status,
3233
3772
  ...typeof type === "string" && type !== "" && { code: type },
@@ -3417,22 +3956,22 @@ function buildCredentials(options) {
3417
3956
  var MONTHS = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
3418
3957
  var DAY_MS = 864e5;
3419
3958
  var HALF_YEAR_DAYS = 184;
3420
- function resolveHostDate(text, referenceDate, options = {}) {
3959
+ function resolveHostDate(text2, referenceDate, options = {}) {
3421
3960
  const reference = referenceDay(referenceDate);
3422
3961
  const direction = options.direction ?? "past";
3423
3962
  if (direction !== "past" && direction !== "nearest") {
3424
3963
  throw new TypeError("sabre-client: direction debe ser 'past' o 'nearest'");
3425
3964
  }
3426
- if (typeof text !== "string") return void 0;
3427
- const parsed = parseHostDate(text.trim().toUpperCase());
3965
+ if (typeof text2 !== "string") return void 0;
3966
+ const parsed = parseHostDate(text2.trim().toUpperCase());
3428
3967
  if (parsed === void 0) return void 0;
3429
3968
  const year = parsed.year ?? resolveYear(parsed.month, parsed.day, reference, direction);
3430
3969
  if (year === void 0 || !isValidDate(year, parsed.month, parsed.day)) return void 0;
3431
3970
  const date = `${pad(year, 4)}-${pad(parsed.month, 2)}-${pad(parsed.day, 2)}`;
3432
3971
  return parsed.time === void 0 ? date : `${date}T${parsed.time}`;
3433
3972
  }
3434
- function parseHostDate(text) {
3435
- let match = /^(\d{1,2})([A-Z]{3})(\d{2})?$/.exec(text);
3973
+ function parseHostDate(text2) {
3974
+ let match = /^(\d{1,2})([A-Z]{3})(\d{2})?$/.exec(text2);
3436
3975
  if (match !== null) {
3437
3976
  const month2 = MONTHS.indexOf(match[2]) + 1;
3438
3977
  if (month2 === 0) return void 0;
@@ -3442,7 +3981,7 @@ function parseHostDate(text) {
3442
3981
  day: Number(match[1])
3443
3982
  };
3444
3983
  }
3445
- match = /^(?:(\d{4})-)?(\d{2})-(\d{2})(?:T(\d{2}):(\d{2}))?$/.exec(text);
3984
+ match = /^(?:(\d{4})-)?(\d{2})-(\d{2})(?:T(\d{2}):(\d{2}))?$/.exec(text2);
3446
3985
  if (match === null) return void 0;
3447
3986
  const [, year, month, day, hours, minutes] = match;
3448
3987
  if (hours !== void 0 && (Number(hours) > 23 || Number(minutes) > 59)) return void 0;
@@ -3643,8 +4182,8 @@ function parseSegment(line, referenceDate) {
3643
4182
  text: line.trim()
3644
4183
  };
3645
4184
  }
3646
- function parseTicketingEntry(number, text, referenceDate) {
3647
- const ticketed = TICKETED.exec(text);
4185
+ function parseTicketingEntry(number, text2, referenceDate) {
4186
+ const ticketed = TICKETED.exec(text2);
3648
4187
  if (ticketed !== null) {
3649
4188
  const [, date, pseudoCityCode, agentSine] = ticketed;
3650
4189
  return {
@@ -3653,10 +4192,10 @@ function parseTicketingEntry(number, text, referenceDate) {
3653
4192
  ...date !== void 0 && withDate(date, referenceDate),
3654
4193
  ...pseudoCityCode !== void 0 && { pseudoCityCode },
3655
4194
  ...agentSine !== void 0 && { agentSine },
3656
- text
4195
+ text: text2
3657
4196
  };
3658
4197
  }
3659
- const arrangement = ARRANGEMENT.exec(text);
4198
+ const arrangement = ARRANGEMENT.exec(text2);
3660
4199
  if (arrangement !== null) {
3661
4200
  const [, code, pseudoCityCode, date] = arrangement;
3662
4201
  return {
@@ -3664,11 +4203,11 @@ function parseTicketingEntry(number, text, referenceDate) {
3664
4203
  code,
3665
4204
  ...date !== void 0 && withDate(date, referenceDate),
3666
4205
  ...pseudoCityCode !== void 0 && { pseudoCityCode },
3667
- text
4206
+ text: text2
3668
4207
  };
3669
4208
  }
3670
- const ticket = TICKET.exec(text);
3671
- if (ticket !== null) return { number, code: ticket[1], ticketNumber: ticket[2], text };
4209
+ const ticket = TICKET.exec(text2);
4210
+ if (ticket !== null) return { number, code: ticket[1], ticketNumber: ticket[2], text: text2 };
3672
4211
  return void 0;
3673
4212
  }
3674
4213
  function lastSignatureIndex(lines) {
@@ -3689,12 +4228,12 @@ function parseSignature(line, referenceDate) {
3689
4228
  locator
3690
4229
  };
3691
4230
  }
3692
- function withDate(text, referenceDate) {
3693
- const date = resolveHostDate(text, referenceDate, { direction: "nearest" });
4231
+ function withDate(text2, referenceDate) {
4232
+ const date = resolveHostDate(text2, referenceDate, { direction: "nearest" });
3694
4233
  return date === void 0 ? {} : { date };
3695
4234
  }
3696
- function hostTime(text) {
3697
- const match = /^(\d{1,2})(\d{2})([APNM])?$/.exec(text);
4235
+ function hostTime(text2) {
4236
+ const match = /^(\d{1,2})(\d{2})([APNM])?$/.exec(text2);
3698
4237
  if (match === null) return void 0;
3699
4238
  let hours = Number(match[1]);
3700
4239
  const minutes = Number(match[2]);
@@ -3714,9 +4253,9 @@ function hostTime(text) {
3714
4253
  // src/queue/queue-place-remark.ts
3715
4254
  var MONTHS2 = /* @__PURE__ */ new Set(["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]);
3716
4255
  var REMARK = /^([A-Z0-9]{3,4})(\d{2})([A-Z]{3})(\d{1,3})\/(\d{1,3})$/;
3717
- function parseQueuePlaceRemark(text) {
3718
- if (typeof text !== "string") return null;
3719
- const match = REMARK.exec(text.trim());
4256
+ function parseQueuePlaceRemark(text2) {
4257
+ if (typeof text2 !== "string") return null;
4258
+ const match = REMARK.exec(text2.trim());
3720
4259
  if (match === null) return null;
3721
4260
  const [, pcc, day, month, queueText, picText] = match;
3722
4261
  const dayNumber2 = Number(day);
@@ -3811,8 +4350,9 @@ function fareComponent(fareComponentId, component) {
3811
4350
  }
3812
4351
 
3813
4352
  // src/index.ts
3814
- var VERSION = "0.6.0";
4353
+ var VERSION = "0.7.0";
3815
4354
  export {
4355
+ MAX_COMMAND_LENGTH,
3816
4356
  MESSAGE_QUEUE,
3817
4357
  Sabre,
3818
4358
  SabreBusinessError,
@@ -3821,6 +4361,7 @@ export {
3821
4361
  SabreLegacy,
3822
4362
  SabreOrchestrationError,
3823
4363
  SabreSessionError,
4364
+ SabreUncertainOutcomeError,
3824
4365
  SabreWarning,
3825
4366
  VERSION,
3826
4367
  buildBookingFlightDetails,
@@ -3830,6 +4371,7 @@ export {
3830
4371
  isMessageQueue,
3831
4372
  parseQueueParagraph,
3832
4373
  parseQueuePlaceRemark,
3833
- resolveHostDate
4374
+ resolveHostDate,
4375
+ sabreCommandLength
3834
4376
  };
3835
4377
  //# sourceMappingURL=index.js.map