uapi-json 1.17.3 → 1.17.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uapi-json",
3
- "version": "1.17.3",
3
+ "version": "1.17.5",
4
4
  "description": "Travelport Universal API",
5
5
  "main": "src/",
6
6
  "files": [
@@ -37,7 +37,7 @@
37
37
  ],
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "axios": "^1.7.7",
40
+ "axios": "^1.9.0",
41
41
  "galileo-screen": "1.0.5",
42
42
  "handlebars": "^4.7.8",
43
43
  "handlebars-helper-equal": "^1.0.0",
@@ -53,11 +53,11 @@
53
53
  "eslint": "^8.39.0",
54
54
  "eslint-config-airbnb-base": "^15.0.0",
55
55
  "eslint-plugin-import": "^2.29.0",
56
- "mocha": "^10.7.3",
56
+ "mocha": "^11.5.0",
57
57
  "nyc": "^17.1.0",
58
58
  "proxyquire": "^2.1.3",
59
59
  "readline2": "^1.0.1",
60
- "sinon": "^19.0.2",
60
+ "sinon": "^20.0.0",
61
61
  "sinon-chai": "^3.7.0"
62
62
  }
63
63
  }
@@ -585,9 +585,8 @@ function getTicketFromEtr(etr, obj, allowNoProviderLocatorCodeRetrieval = false)
585
585
  const exchangedTickets = [];
586
586
 
587
587
  const allCoupons = ticketsList.map((ticket) => {
588
- return Object.entries(ticket['air:Coupon']).map(([couponKey, coupon]) => {
588
+ return Object.values(ticket['air:Coupon']).map((coupon) => {
589
589
  return {
590
- key: couponKey,
591
590
  ticketNumber: ticket.TicketNumber,
592
591
  couponNumber: coupon.CouponNumber,
593
592
  from: coupon.Origin,
@@ -607,59 +606,54 @@ function getTicketFromEtr(etr, obj, allowNoProviderLocatorCodeRetrieval = false)
607
606
  return all.concat(nextChunk);
608
607
  }, []);
609
608
 
610
- const tickets = ticketsList.map(
611
- (ticket) => {
612
- if (ticket['air:ExchangedTicketInfo']) {
613
- ticket['air:ExchangedTicketInfo'].forEach(
614
- (t) => exchangedTickets.push(t.Number)
615
- );
616
- }
609
+ // Filling exchanged tickets array
610
+ ticketsList.forEach((ticket) => {
611
+ if (ticket['air:ExchangedTicketInfo']) {
612
+ ticket['air:ExchangedTicketInfo'].forEach(
613
+ (t) => exchangedTickets.push(t.Number)
614
+ );
615
+ }
616
+ });
617
617
 
618
- const coupons = Object.keys(ticket['air:Coupon']).map(
619
- (couponKey) => {
620
- const allCouponsIndex = allCoupons.findIndex((ac) => ac.key === couponKey);
621
- const coupon = allCoupons[allCouponsIndex];
622
- const nextCoupon = allCoupons[allCouponsIndex + 1];
623
-
624
- let bookingInfo = null;
625
- // looking for fareInfo by it's fareBasis
626
- // and for bookingInfo by correct FareInfoRef
627
- if (airPricingInfo && airPricingInfo['air:FareInfo']) {
628
- Object.keys(airPricingInfo['air:FareInfo']).forEach(
629
- (fareKey) => {
630
- const fare = airPricingInfo['air:FareInfo'][fareKey];
631
- if (fare.FareBasis === coupon.FareBasis
632
- && airPricingInfo['air:BookingInfo']) {
633
- const bInfo = airPricingInfo['air:BookingInfo'].find(
634
- (info) => info.FareInfoRef === fareKey
635
- );
636
-
637
- if (bInfo) {
638
- bookingInfo = bInfo;
639
- }
640
- }
641
- }
618
+ // Getting ticket coupons
619
+ const ticketsObject = allCoupons.reduce((acc, coupon, index) => {
620
+ const { ticketNumber } = coupon;
621
+ const ticket = acc[ticketNumber] || { ticketNumber, coupons: [] };
622
+ const { coupons } = ticket;
623
+ const nextCoupon = allCoupons[index + 1];
624
+
625
+ let bookingInfo = null;
626
+ // looking for fareInfo by it's fareBasis
627
+ // and for bookingInfo by correct FareInfoRef
628
+ if (airPricingInfo && airPricingInfo['air:FareInfo']) {
629
+ Object.keys(airPricingInfo['air:FareInfo']).forEach(
630
+ (fareKey) => {
631
+ const fare = airPricingInfo['air:FareInfo'][fareKey];
632
+ if (fare.FareBasis === coupon.FareBasis && airPricingInfo['air:BookingInfo']) {
633
+ const bInfo = airPricingInfo['air:BookingInfo'].find(
634
+ (info) => info.FareInfoRef === fareKey
642
635
  );
643
- }
644
636
 
645
- return {
646
- ...coupon,
647
- stopover: (
648
- nextCoupon
649
- ? nextCoupon.stopover
650
- : true
651
- ),
652
- ...(bookingInfo !== null ? { serviceClass: bookingInfo.CabinClass } : null)
653
- };
637
+ if (bInfo) {
638
+ bookingInfo = bInfo;
639
+ }
640
+ }
654
641
  }
655
642
  );
656
-
657
- return {
658
- ticketNumber: ticket.TicketNumber,
659
- coupons,
660
- };
661
643
  }
662
- );
644
+ const couponData = {
645
+ ...coupon,
646
+ stopover: (
647
+ nextCoupon
648
+ ? nextCoupon.stopover
649
+ : true
650
+ ),
651
+ ...(bookingInfo !== null ? { serviceClass: bookingInfo.CabinClass } : null)
652
+ };
653
+ return { ...acc, [ticketNumber]: { ...ticket, coupons: [...coupons, couponData] } };
654
+ }, {});
655
+
656
+ const tickets = Object.values(ticketsObject);
663
657
 
664
658
  const taxes = (airPricingInfo && airPricingInfo['air:TaxInfo'])
665
659
  ? Object.keys(airPricingInfo['air:TaxInfo']).map(
@@ -117,50 +117,49 @@ module.exports = function (settings) {
117
117
  };
118
118
 
119
119
  // Getting session token
120
- const getSessionToken = () => new Promise((resolve, reject) => {
120
+ const getSessionToken = async () => {
121
+ // Return error if not in correct state
121
122
  if (state.terminalState === TERMINAL_STATE_BUSY) {
122
- reject(new TerminalRuntimeError.TerminalIsBusy());
123
- return;
123
+ throw new TerminalRuntimeError.TerminalIsBusy();
124
124
  }
125
125
  if (state.terminalState === TERMINAL_STATE_CLOSED) {
126
- reject(new TerminalRuntimeError.TerminalIsClosed());
127
- return;
126
+ throw new TerminalRuntimeError.TerminalIsClosed();
128
127
  }
129
- Object.assign(state, {
130
- terminalState: TERMINAL_STATE_BUSY,
131
- });
128
+
129
+ state.terminalState = TERMINAL_STATE_BUSY;
130
+
132
131
  // Return token if already obtained
133
132
  if (state.sessionToken !== null) {
134
- resolve(state.sessionToken);
135
- return;
133
+ return state.sessionToken;
134
+ }
135
+
136
+ const { sessionToken } = await service.getSessionToken({ timeout });
137
+ state.sessionToken = sessionToken;
138
+
139
+ if (!emulatePcc) {
140
+ state.terminalState = TERMINAL_STATE_READY;
141
+ return state.sessionToken;
142
+ }
143
+
144
+ const response = await service.executeCommand({
145
+ sessionToken,
146
+ command: `SEM/${emulatePcc}/AG`,
147
+ });
148
+
149
+ if (response[0].match(/duty code not authorised/i)) {
150
+ throw new TerminalRuntimeError.TerminalAuthIssue(response);
151
+ }
152
+
153
+ if (response[0].match(/INVALID ACCOUNT/)) {
154
+ throw new TerminalRuntimeError.InvalidAccount(response);
136
155
  }
137
- // Getting token
138
- service.getSessionToken({ timeout })
139
- .then((tokenData) => {
140
- // Remember sesion token
141
- Object.assign(state, tokenData);
142
- // Return if no emulation needed
143
- if (!emulatePcc) {
144
- return tokenData.sessionToken;
145
- }
146
- // Emulate pcc
147
- return service.executeCommand({
148
- sessionToken: tokenData.sessionToken,
149
- command: `SEM/${emulatePcc}/AG`,
150
- }).then((response) => {
151
- if (response[0].match(/duty code not authorised/i)) {
152
- return Promise.reject(new TerminalRuntimeError.TerminalAuthIssue(response));
153
- }
154
-
155
- if (!response[0].match(/^PROCEED/)) {
156
- return Promise.reject(new TerminalRuntimeError.TerminalEmulationFailed(response));
157
- }
158
- return Promise.resolve(tokenData.sessionToken);
159
- });
160
- })
161
- .then(resolve)
162
- .catch(reject);
163
- });
156
+
157
+ if (!response[0].match(/^PROCEED/)) {
158
+ throw new TerminalRuntimeError.TerminalEmulationFailed(response);
159
+ }
160
+
161
+ return sessionToken;
162
+ };
164
163
 
165
164
  // Runtime error handling
166
165
  const executeCommandWithRetry = async (command, times = DEFAULT_RETRY_TIMES) => {
@@ -210,7 +209,12 @@ module.exports = function (settings) {
210
209
  const getTerminalId = (sessionToken) => getHashSubstr(sessionToken);
211
210
 
212
211
  const terminal = {
213
- getToken: getSessionToken,
212
+ getToken: async () => {
213
+ await getSessionToken();
214
+ // Needed here as getSessionToken marks terminal as busy
215
+ state.terminalState = TERMINAL_STATE_READY;
216
+ return state.sessionToken;
217
+ },
214
218
  executeCommand: async (command, stopMD = defaultStopMD) => {
215
219
  try {
216
220
  const sessionToken = await getSessionToken();
@@ -47,6 +47,7 @@ Object.assign(TerminalRuntimeError, createErrorsList({
47
47
  ErrorClosingSession: 'Error closing session',
48
48
  NoAgreement: ['There is no agreement between current pcc and you trying to reach', errorCodes.Validation],
49
49
  TerminalAuthIssue: ['Temporary terminal auth issue. Please, try again later', errorCodes.Validation],
50
+ InvalidAccount: ['Invalid account', errorCodes.Validation],
50
51
  TerminalUnexpectedError: ['Unexpected error message is returned by Travelport system. Please check PNR and try again later.', errorCodes.Validation],
51
52
  TerminalUnexpectedFinancialError: ['Unexpected error message is returned by Travelport system. Please check PNR and new Fare calculation. If the problem persists, contact your local helpdesk.', errorCodes.Validation],
52
53
  }, TerminalRuntimeError));