@admin-layout/client 12.2.5-alpha.2 → 12.2.5-alpha.27
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/lib/__tests__/ApplicationErrorHandlerCommon.ssr.test.d.ts +2 -0
- package/lib/__tests__/ApplicationErrorHandlerCommon.ssr.test.d.ts.map +1 -0
- package/lib/components/ApplicationErrorHandlerCommon.d.ts.map +1 -1
- package/lib/components/ApplicationErrorHandlerCommon.js +8 -3
- package/lib/components/ApplicationErrorHandlerCommon.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.native.js +1 -1
- package/lib/utils/bookingCard.d.ts +98 -0
- package/lib/utils/bookingCard.d.ts.map +1 -0
- package/lib/utils/bookingCard.js +166 -0
- package/lib/utils/bookingCard.js.map +1 -0
- package/lib/utils/bookingCard.test.d.ts +2 -0
- package/lib/utils/bookingCard.test.d.ts.map +1 -0
- package/lib/utils/flightCards.d.ts +120 -0
- package/lib/utils/flightCards.d.ts.map +1 -1
- package/lib/utils/flightCards.js +370 -12
- package/lib/utils/flightCards.js.map +1 -1
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/resultCards.d.ts +246 -0
- package/lib/utils/resultCards.d.ts.map +1 -0
- package/lib/utils/resultCards.js +641 -0
- package/lib/utils/resultCards.js.map +1 -0
- package/lib/utils/resultCards.test.d.ts +2 -0
- package/lib/utils/resultCards.test.d.ts.map +1 -0
- package/package.json +2 -2
package/lib/utils/flightCards.js
CHANGED
|
@@ -12,9 +12,24 @@
|
|
|
12
12
|
*/
|
|
13
13
|
const WALL_CLOCK = /T(\d{2}):(\d{2})/;
|
|
14
14
|
const CALENDAR_DATE = /^(\d{4})-(\d{2})-(\d{2})/;
|
|
15
|
+
/**
|
|
16
|
+
* "6:28 PM" from the airport-local wall clock in the ISO string, whatever zone the viewer is in.
|
|
17
|
+
* Twelve-hour like `dateLabel`'s en-US, and built by hand so the server and the browser agree.
|
|
18
|
+
*/
|
|
15
19
|
const wallClock = (iso) => {
|
|
16
20
|
const m = iso ? WALL_CLOCK.exec(iso) : null;
|
|
17
|
-
|
|
21
|
+
if (!m)
|
|
22
|
+
return undefined;
|
|
23
|
+
const hour = Number(m[1]);
|
|
24
|
+
return `${hour % 12 || 12}:${m[2]} ${hour < 12 ? 'AM' : 'PM'}`;
|
|
25
|
+
};
|
|
26
|
+
/** Minutes since 1970 of the airport-local date and wall clock, never converted to a zone. */
|
|
27
|
+
const wallOrder = (iso) => {
|
|
28
|
+
const day = iso ? CALENDAR_DATE.exec(iso) : null;
|
|
29
|
+
const time = iso ? WALL_CLOCK.exec(iso) : null;
|
|
30
|
+
if (!day || !time)
|
|
31
|
+
return undefined;
|
|
32
|
+
return Date.UTC(Number(day[1]), Number(day[2]) - 1, Number(day[3]), Number(time[1]), Number(time[2])) / 60_000;
|
|
18
33
|
};
|
|
19
34
|
const utcDay = (iso) => {
|
|
20
35
|
const m = iso ? CALENDAR_DATE.exec(iso) : null;
|
|
@@ -56,31 +71,207 @@ const durationLabel = (minutes) => {
|
|
|
56
71
|
return `${m}m`;
|
|
57
72
|
return m === 0 ? `${h}h` : `${h}h ${m}m`;
|
|
58
73
|
};
|
|
59
|
-
const
|
|
60
|
-
if (item.priceLabel)
|
|
61
|
-
return item.priceLabel;
|
|
62
|
-
if (typeof item.price !== 'number' || !Number.isFinite(item.price))
|
|
63
|
-
return undefined;
|
|
74
|
+
const formatCurrency = (amount, currency) => {
|
|
64
75
|
try {
|
|
65
|
-
return new Intl.NumberFormat('en-US', {
|
|
76
|
+
return (new Intl.NumberFormat('en-US', {
|
|
66
77
|
style: 'currency',
|
|
67
78
|
currency,
|
|
68
79
|
maximumFractionDigits: 0,
|
|
69
|
-
})
|
|
80
|
+
})
|
|
81
|
+
.format(amount)
|
|
82
|
+
// Intl pads "PKR 17,500" with a no-break space; a plain one wraps and compares sanely.
|
|
83
|
+
.replace(/\u00a0/g, ' '));
|
|
70
84
|
}
|
|
71
85
|
catch {
|
|
72
86
|
// An unknown currency code must not take the whole card down.
|
|
73
|
-
return `${Math.round(
|
|
87
|
+
return `${Math.round(amount)} ${currency}`;
|
|
74
88
|
}
|
|
75
89
|
};
|
|
90
|
+
/** A provider label written as "<ISO code> <amount>", e.g. "USD 61.00" or "PKR 17,500". */
|
|
91
|
+
const CODE_AMOUNT = /^([A-Z]{3})\s+([\d,]+(?:\.\d+)?)$/;
|
|
92
|
+
const flightPrice = (item, currency = 'USD') => {
|
|
93
|
+
if (item.priceLabel) {
|
|
94
|
+
// "USD 61.00" reads as "$61": same currency, the way a fare is printed.
|
|
95
|
+
const m = CODE_AMOUNT.exec(item.priceLabel.trim());
|
|
96
|
+
if (m) {
|
|
97
|
+
const amount = Number(m[2].replace(/,/g, ''));
|
|
98
|
+
if (Number.isFinite(amount))
|
|
99
|
+
return formatCurrency(amount, m[1]);
|
|
100
|
+
}
|
|
101
|
+
return item.priceLabel;
|
|
102
|
+
}
|
|
103
|
+
if (typeof item.price !== 'number' || !Number.isFinite(item.price))
|
|
104
|
+
return undefined;
|
|
105
|
+
return formatCurrency(item.price, currency);
|
|
106
|
+
};
|
|
107
|
+
/** The numeric fare, from `price` or parsed out of the label; undefined when neither is usable. */
|
|
108
|
+
const flightPriceValue = (item) => {
|
|
109
|
+
if (typeof item.price === 'number' && Number.isFinite(item.price) && item.price > 0)
|
|
110
|
+
return item.price;
|
|
111
|
+
const digits = item.priceLabel?.replace(/[^\d.]/g, '');
|
|
112
|
+
const parsed = digits ? Number(digits) : NaN;
|
|
113
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
114
|
+
};
|
|
115
|
+
const CABIN_LABELS = {
|
|
116
|
+
economy: 'Economy',
|
|
117
|
+
premium_economy: 'Premium economy',
|
|
118
|
+
premium: 'Premium economy',
|
|
119
|
+
business: 'Business',
|
|
120
|
+
first: 'First',
|
|
121
|
+
};
|
|
122
|
+
/** "premium_economy" → "Premium economy"; plain economy is the default and reads as nothing. */
|
|
123
|
+
const cabinLabel = (cabinClass) => {
|
|
124
|
+
const key = cabinClass
|
|
125
|
+
?.trim()
|
|
126
|
+
.toLowerCase()
|
|
127
|
+
.replace(/[\s-]+/g, '_');
|
|
128
|
+
if (!key || key === 'economy')
|
|
129
|
+
return undefined;
|
|
130
|
+
return CABIN_LABELS[key] ?? key.replace(/_/g, ' ').replace(/^\w/, (c) => c.toUpperCase());
|
|
131
|
+
};
|
|
132
|
+
const bagsLabel = (checked, carryOn) => {
|
|
133
|
+
const n = (v) => (typeof v === 'number' && Number.isFinite(v) && v >= 0 ? Math.floor(v) : undefined);
|
|
134
|
+
const bags = n(checked);
|
|
135
|
+
if (bags != null && bags > 0)
|
|
136
|
+
return bags === 1 ? '1 checked bag' : `${bags} checked bags`;
|
|
137
|
+
if (bags === 0)
|
|
138
|
+
return (n(carryOn) ?? 0) > 0 ? 'Carry-on only' : 'No checked bag';
|
|
139
|
+
return undefined;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* "Lufthansa Economy Comfort · 1 checked bag · One way": the airline with its
|
|
143
|
+
* fare brand (or a non-economy cabin), the bags the fare includes, separate
|
|
144
|
+
* tickets when they are, and the trip type. Undefined when the offer says
|
|
145
|
+
* nothing about its fare beyond the trip type, so a card never shows a line
|
|
146
|
+
* of defaults.
|
|
147
|
+
*/
|
|
148
|
+
const fareLineLabel = (flight, roundTrip) => {
|
|
149
|
+
const brand = flight.fareBrand?.trim() || cabinLabel(flight.cabinClass);
|
|
150
|
+
const bags = bagsLabel(flight.checkedBags, flight.carryOnBags);
|
|
151
|
+
const selfTransfer = flight.selfTransfer === true ? 'Self-transfer (separate tickets)' : undefined;
|
|
152
|
+
if (!brand && !bags && !selfTransfer)
|
|
153
|
+
return undefined;
|
|
154
|
+
const fare = [flight.airline?.trim(), brand].filter(Boolean).join(' ') || undefined;
|
|
155
|
+
return [fare, bags, selfTransfer, roundTrip ? 'Round trip' : 'One way'].filter(Boolean).join(' · ');
|
|
156
|
+
};
|
|
157
|
+
/** An IATA (2 chars, at least one letter) or ICAO (3 letters) airline code, then the number. */
|
|
158
|
+
const FLIGHT_NUMBER = /^([A-Z]{2,3}|[A-Z][0-9]|[0-9][A-Z])\s*(\d{1,4}[A-Z]?)$/i;
|
|
159
|
+
/** "PA201" → "PA 201"; anything else is shown as written. */
|
|
160
|
+
const formatFlightNumber = (raw) => {
|
|
161
|
+
const m = FLIGHT_NUMBER.exec(raw.trim());
|
|
162
|
+
return m ? `${m[1].toUpperCase()} ${m[2].toUpperCase()}` : raw.trim();
|
|
163
|
+
};
|
|
164
|
+
const flightNumberLabel = (numbers) => {
|
|
165
|
+
const list = (numbers ?? []).map((n) => n?.trim()).filter(Boolean);
|
|
166
|
+
if (list.length === 0)
|
|
167
|
+
return undefined;
|
|
168
|
+
const shown = list.slice(0, 2).map(formatFlightNumber);
|
|
169
|
+
return list.length > 2 ? `${shown.join(' · ')} +${list.length - 2}` : shown.join(' · ');
|
|
170
|
+
};
|
|
171
|
+
/** The two-letter tile for an airline: its IATA prefix when a flight number carries one, else initials. */
|
|
172
|
+
const airlineCode = (airline, flightNumbers) => {
|
|
173
|
+
const first = flightNumbers?.find((n) => n && FLIGHT_NUMBER.test(n.trim()));
|
|
174
|
+
if (first)
|
|
175
|
+
return FLIGHT_NUMBER.exec(first.trim())[1].toUpperCase().slice(0, 2);
|
|
176
|
+
const words = (airline ?? '')
|
|
177
|
+
.split(/[\s,/&-]+/)
|
|
178
|
+
.map((w) => w.replace(/[^A-Za-z0-9]/g, ''))
|
|
179
|
+
.filter(Boolean);
|
|
180
|
+
if (words.length === 0)
|
|
181
|
+
return '✈';
|
|
182
|
+
if (words.length === 1)
|
|
183
|
+
return words[0].slice(0, 2).toUpperCase();
|
|
184
|
+
return (words[0][0] + words[1][0]).toUpperCase();
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Carriers whose IATA code the logo service has a real mark for, by name. The service answers some
|
|
188
|
+
* codes it does not know with a generic grey tail fin the page cannot tell from a logo (Vistara,
|
|
189
|
+
* Alliance Air and Star Air get one), so only codes checked to have their own mark are here.
|
|
190
|
+
*/
|
|
191
|
+
const AIRLINE_LOGO_CODES = {
|
|
192
|
+
akasaair: 'QP',
|
|
193
|
+
akasa: 'QP',
|
|
194
|
+
indigo: '6E',
|
|
195
|
+
airindia: 'AI',
|
|
196
|
+
airindiaexpress: 'IX',
|
|
197
|
+
spicejet: 'SG',
|
|
198
|
+
emirates: 'EK',
|
|
199
|
+
qatarairways: 'QR',
|
|
200
|
+
etihad: 'EY',
|
|
201
|
+
etihadairways: 'EY',
|
|
202
|
+
singaporeairlines: 'SQ',
|
|
203
|
+
lufthansa: 'LH',
|
|
204
|
+
britishairways: 'BA',
|
|
205
|
+
united: 'UA',
|
|
206
|
+
unitedairlines: 'UA',
|
|
207
|
+
delta: 'DL',
|
|
208
|
+
deltaairlines: 'DL',
|
|
209
|
+
american: 'AA',
|
|
210
|
+
americanairlines: 'AA',
|
|
211
|
+
jetblue: 'B6',
|
|
212
|
+
southwest: 'WN',
|
|
213
|
+
southwestairlines: 'WN',
|
|
214
|
+
alaska: 'AS',
|
|
215
|
+
alaskaairlines: 'AS',
|
|
216
|
+
hawaiian: 'HA',
|
|
217
|
+
hawaiianairlines: 'HA',
|
|
218
|
+
allegiant: 'G4',
|
|
219
|
+
allegiantair: 'G4',
|
|
220
|
+
suncountry: 'SY',
|
|
221
|
+
suncountryairlines: 'SY',
|
|
222
|
+
aircanada: 'AC',
|
|
223
|
+
westjet: 'WS',
|
|
224
|
+
ana: 'NH',
|
|
225
|
+
allnipponairways: 'NH',
|
|
226
|
+
jal: 'JL',
|
|
227
|
+
japanairlines: 'JL',
|
|
228
|
+
cathaypacific: 'CX',
|
|
229
|
+
thaiairways: 'TG',
|
|
230
|
+
turkishairlines: 'TK',
|
|
231
|
+
klm: 'KL',
|
|
232
|
+
airfrance: 'AF',
|
|
233
|
+
ryanair: 'FR',
|
|
234
|
+
easyjet: 'U2',
|
|
235
|
+
qantas: 'QF',
|
|
236
|
+
virginatlantic: 'VS',
|
|
237
|
+
frontier: 'F9',
|
|
238
|
+
frontierairlines: 'F9',
|
|
239
|
+
spirit: 'NK',
|
|
240
|
+
spiritairlines: 'NK',
|
|
241
|
+
};
|
|
242
|
+
const KNOWN_LOGO_CODES = new Set(Object.values(AIRLINE_LOGO_CODES));
|
|
243
|
+
const AIRLINE_LOGO_SERVICE = 'https://www.gstatic.com/flights/airline_logos/70px';
|
|
244
|
+
/** The airline's own mark by IATA code - a flight number's, else the one its name is known by. */
|
|
245
|
+
const airlineLogoUrl = (airline, flightNumbers) => {
|
|
246
|
+
const first = flightNumbers?.find((n) => n && FLIGHT_NUMBER.test(n.trim()));
|
|
247
|
+
const fromNumber = first ? FLIGHT_NUMBER.exec(first.trim())[1].toUpperCase() : undefined;
|
|
248
|
+
const code = fromNumber && KNOWN_LOGO_CODES.has(fromNumber)
|
|
249
|
+
? fromNumber
|
|
250
|
+
: AIRLINE_LOGO_CODES[(airline ?? '').toLowerCase().replace(/[^a-z]/g, '')];
|
|
251
|
+
return code ? `${AIRLINE_LOGO_SERVICE}/${code}.png` : undefined;
|
|
252
|
+
};
|
|
253
|
+
/** A stable palette slot for an airline name, so Airblue is the same colour on every card. */
|
|
254
|
+
const airlineTone = (airline, slots = 8) => {
|
|
255
|
+
const s = (airline ?? '').toLowerCase();
|
|
256
|
+
let h = 0;
|
|
257
|
+
for (let i = 0; i < s.length; i++)
|
|
258
|
+
h = (h * 31 + s.charCodeAt(i)) >>> 0;
|
|
259
|
+
return h % slots;
|
|
260
|
+
};
|
|
76
261
|
const sliceView = (s) => ({
|
|
77
262
|
origin: s.origin,
|
|
78
263
|
destination: s.destination,
|
|
79
264
|
departTime: wallClock(s.departAt),
|
|
80
265
|
arriveTime: wallClock(s.arriveAt),
|
|
266
|
+
departOrder: wallOrder(s.departAt),
|
|
81
267
|
dayOffset: dayOffset(s.departAt, s.arriveAt),
|
|
82
268
|
stops: stopsLabel(s.stops),
|
|
269
|
+
stopCount: typeof s.stops === 'number' && Number.isFinite(s.stops) && s.stops >= 0 ? s.stops : undefined,
|
|
83
270
|
duration: durationLabel(s.durationMinutes),
|
|
271
|
+
durationMinutes: typeof s.durationMinutes === 'number' && Number.isFinite(s.durationMinutes) && s.durationMinutes > 0
|
|
272
|
+
? s.durationMinutes
|
|
273
|
+
: undefined,
|
|
274
|
+
date: dateLabel(s.departAt),
|
|
84
275
|
});
|
|
85
276
|
/** True when the attachment is a flight result, so the card shows flights, not stays. */
|
|
86
277
|
const isFlightAttachment = (a) => !!a?.properties?.some((p) => (p.flight?.slices?.length ?? 0) > 0);
|
|
@@ -95,17 +286,46 @@ const toFlightCard = (item, index, currency) => {
|
|
|
95
286
|
if (!flight || slices.length === 0)
|
|
96
287
|
return null;
|
|
97
288
|
const outbound = flight.slices[0];
|
|
98
|
-
const seller = flight.seller?.trim();
|
|
289
|
+
const seller = flight.seller?.trim() || undefined;
|
|
290
|
+
const airline = flight.airline?.trim() || undefined;
|
|
99
291
|
const date = dateLabel(outbound.departAt);
|
|
100
292
|
const header = [seller, date].filter(Boolean).join(' · ') || `${slices[0].origin} to ${slices[0].destination}`;
|
|
101
293
|
// One direction: say how it flies. A round trip already shows stops per
|
|
102
294
|
// row, so the footer names the trip type instead of repeating them.
|
|
103
295
|
const how = roundTrip ? 'Round trip' : slices[0].stops;
|
|
104
|
-
const footer = [
|
|
296
|
+
const footer = [airline || item.title, how].filter(Boolean).join(' · ');
|
|
297
|
+
const fareLine = fareLineLabel(flight, roundTrip);
|
|
105
298
|
const price = flightPrice(item, currency);
|
|
106
299
|
const spoken = slices
|
|
107
300
|
.map((s) => `${s.origin} ${s.departTime ?? ''} to ${s.destination} ${s.arriveTime ?? ''}${s.dayOffset === '+1' ? ' next day' : s.dayOffset ? ` ${s.dayOffset.slice(1)} days later` : ''}${s.stops ? `, ${s.stops.toLowerCase()}` : ''}`)
|
|
108
301
|
.join('; returning ');
|
|
302
|
+
const out = slices[0];
|
|
303
|
+
const back = roundTrip ? slices[slices.length - 1] : undefined;
|
|
304
|
+
const flightNumber = flightNumberLabel(flight.flightNumbers);
|
|
305
|
+
const carrier = airline || item.title;
|
|
306
|
+
const bookReply = back
|
|
307
|
+
? [
|
|
308
|
+
`Book the ${carrier ? `${carrier} ` : ''}round trip`,
|
|
309
|
+
flightNumber ? ` ${flightNumber}` : '',
|
|
310
|
+
`: ${out.origin} to ${out.destination}`,
|
|
311
|
+
out.departTime ? ` at ${out.departTime}` : '',
|
|
312
|
+
date ? ` on ${date}` : '',
|
|
313
|
+
`, back`,
|
|
314
|
+
back.departTime ? ` at ${back.departTime}` : '',
|
|
315
|
+
back.date ? ` on ${back.date}` : '',
|
|
316
|
+
price ? ` (${price})` : '',
|
|
317
|
+
'.',
|
|
318
|
+
].join('')
|
|
319
|
+
: [
|
|
320
|
+
`Book the ${out.departTime ? `${out.departTime} ` : ''}${carrier ? `${carrier} ` : ''}flight`,
|
|
321
|
+
flightNumber ? ` ${flightNumber}` : '',
|
|
322
|
+
` from ${out.origin} to ${out.destination}`,
|
|
323
|
+
date ? ` on ${date}` : '',
|
|
324
|
+
price ? ` (${price})` : '',
|
|
325
|
+
'.',
|
|
326
|
+
].join('');
|
|
327
|
+
const minutes = slices.map((s) => s.durationMinutes);
|
|
328
|
+
const totalMinutes = minutes.every((m) => m != null) ? minutes.reduce((a, b) => a + b, 0) : undefined;
|
|
109
329
|
return {
|
|
110
330
|
key: item.id ?? `flight-${index}`,
|
|
111
331
|
url: item.url,
|
|
@@ -113,16 +333,154 @@ const toFlightCard = (item, index, currency) => {
|
|
|
113
333
|
sellerInitial: seller ? seller.charAt(0).toUpperCase() : undefined,
|
|
114
334
|
slices,
|
|
115
335
|
footer,
|
|
336
|
+
...(fareLine ? { fareLine } : {}),
|
|
116
337
|
price,
|
|
117
338
|
accessibleLabel: [
|
|
118
339
|
flight.airline,
|
|
119
340
|
spoken.replace(/\s+/g, ' ').trim(),
|
|
341
|
+
fareLine,
|
|
120
342
|
price,
|
|
121
343
|
date,
|
|
122
344
|
seller && `sold by ${seller}`,
|
|
123
345
|
]
|
|
124
346
|
.filter(Boolean)
|
|
125
347
|
.join(', '),
|
|
348
|
+
airline,
|
|
349
|
+
airlineCode: airlineCode(airline, flight.flightNumbers),
|
|
350
|
+
...(airlineLogoUrl(airline, flight.flightNumbers)
|
|
351
|
+
? { airlineLogo: airlineLogoUrl(airline, flight.flightNumbers) }
|
|
352
|
+
: {}),
|
|
353
|
+
airlineTone: airlineTone(airline ?? item.title),
|
|
354
|
+
flightNumber,
|
|
355
|
+
bookReply,
|
|
356
|
+
seller,
|
|
357
|
+
date,
|
|
358
|
+
cabin: cabinLabel(flight.cabinClass),
|
|
359
|
+
roundTrip,
|
|
360
|
+
...(flight.selfTransfer === true ? { selfTransfer: true } : {}),
|
|
361
|
+
priceValue: flightPriceValue(item),
|
|
362
|
+
totalMinutes,
|
|
363
|
+
badges: [],
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
const BADGE_WORDS = {
|
|
367
|
+
cheapest: 'cheapest',
|
|
368
|
+
fastest: 'fastest',
|
|
369
|
+
best: 'best value',
|
|
370
|
+
};
|
|
371
|
+
const flightBadgeLabel = (badge) => badge === 'best' ? 'Best value' : badge === 'cheapest' ? 'Cheapest' : 'Fastest';
|
|
372
|
+
/**
|
|
373
|
+
* Labels the standouts of a result set: the cheapest fare, the shortest trip,
|
|
374
|
+
* and, when it is a third card, the best price-for-time. Needs two priced
|
|
375
|
+
* offers to mean anything; a lone card gets no badge. Cards keep their order.
|
|
376
|
+
* Self-transfer fares only compete when the set has nothing else.
|
|
377
|
+
*/
|
|
378
|
+
const rankFlightCards = (cards) => {
|
|
379
|
+
// Separate tickets are never "Cheapest" or "Fastest" while a protected fare
|
|
380
|
+
// is in the set: the badge would sell a trip whose missed connection
|
|
381
|
+
// nobody covers.
|
|
382
|
+
const pricedAll = cards.filter((c) => c.priceValue != null);
|
|
383
|
+
const pricedProtected = pricedAll.filter((c) => !c.selfTransfer);
|
|
384
|
+
const priced = pricedProtected.length ? pricedProtected : pricedAll;
|
|
385
|
+
if (priced.length < 2)
|
|
386
|
+
return cards.map((c) => ({ ...c, badges: [] }));
|
|
387
|
+
const byPrice = (a, b) => a.priceValue - b.priceValue || (a.totalMinutes ?? Infinity) - (b.totalMinutes ?? Infinity);
|
|
388
|
+
const cheapest = [...priced].sort(byPrice)[0];
|
|
389
|
+
const timed = priced.filter((c) => c.totalMinutes != null);
|
|
390
|
+
const fastest = timed.length
|
|
391
|
+
? [...timed].sort((a, b) => a.totalMinutes - b.totalMinutes || a.priceValue - b.priceValue)[0]
|
|
392
|
+
: undefined;
|
|
393
|
+
let best;
|
|
394
|
+
if (fastest && timed.length >= 2) {
|
|
395
|
+
const minPrice = cheapest.priceValue;
|
|
396
|
+
const minMinutes = fastest.totalMinutes;
|
|
397
|
+
const score = (c) => c.priceValue / minPrice + c.totalMinutes / minMinutes;
|
|
398
|
+
best = [...timed].sort((a, b) => score(a) - score(b) || byPrice(a, b))[0];
|
|
399
|
+
}
|
|
400
|
+
return cards.map((c) => {
|
|
401
|
+
const badges = [];
|
|
402
|
+
if (c === cheapest)
|
|
403
|
+
badges.push('cheapest');
|
|
404
|
+
if (fastest && c === fastest)
|
|
405
|
+
badges.push('fastest');
|
|
406
|
+
// "Best value" only when it is a different card: the cheapest or
|
|
407
|
+
// fastest already says more than a derived score would.
|
|
408
|
+
if (best && c === best && c !== cheapest && c !== fastest)
|
|
409
|
+
badges.push('best');
|
|
410
|
+
if (badges.length === 0)
|
|
411
|
+
return { ...c, badges };
|
|
412
|
+
return {
|
|
413
|
+
...c,
|
|
414
|
+
badges,
|
|
415
|
+
accessibleLabel: `${badges.map((b) => BADGE_WORDS[b]).join(' and ')}, ${c.accessibleLabel}`,
|
|
416
|
+
};
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
/** Every offer as a ranked card; stays and unusable items are skipped. */
|
|
420
|
+
const toFlightCards = (a) => rankFlightCards((a.properties ?? [])
|
|
421
|
+
.map((p, i) => toFlightCard(p, i, a.currency))
|
|
422
|
+
.filter((c) => c !== null));
|
|
423
|
+
/** A stable ordering of the cards; `recommended` is the order the agent returned them in. */
|
|
424
|
+
const sortFlightCards = (cards, sort) => {
|
|
425
|
+
if (sort === 'recommended')
|
|
426
|
+
return cards;
|
|
427
|
+
const metric = (c) => {
|
|
428
|
+
if (sort === 'cheapest')
|
|
429
|
+
return c.priceValue ?? Infinity;
|
|
430
|
+
if (sort === 'fastest')
|
|
431
|
+
return c.totalMinutes ?? Infinity;
|
|
432
|
+
return c.slices[0]?.departOrder ?? Infinity;
|
|
126
433
|
};
|
|
434
|
+
return cards
|
|
435
|
+
.map((c, index) => ({ c, index, m: metric(c) }))
|
|
436
|
+
.sort((a, b) => (a.m < b.m ? -1 : a.m > b.m ? 1 : 0) || a.index - b.index)
|
|
437
|
+
.map((x) => x.c);
|
|
127
438
|
};
|
|
128
|
-
const
|
|
439
|
+
const flightResultSummary = (a, cards = toFlightCards(a)) => {
|
|
440
|
+
const first = cards[0];
|
|
441
|
+
const out = first?.slices[0];
|
|
442
|
+
const back = first?.roundTrip ? first.slices[first.slices.length - 1] : undefined;
|
|
443
|
+
const roundTrip = !!back;
|
|
444
|
+
const dates = new Set(cards.map((c) => c.date ?? ''));
|
|
445
|
+
const sameDate = dates.size <= 1;
|
|
446
|
+
const outDate = sameDate ? first?.date : undefined;
|
|
447
|
+
const date = outDate ? [outDate, back?.date].filter(Boolean).join(' – ') : undefined;
|
|
448
|
+
const priced = cards.filter((c) => c.priceValue != null);
|
|
449
|
+
const cheapestCard = priced.length ? [...priced].sort((x, y) => x.priceValue - y.priceValue)[0] : undefined;
|
|
450
|
+
const sellers = new Set(cards.map((c) => c.seller ?? ''));
|
|
451
|
+
const seller = sellers.size === 1 ? first?.seller : undefined;
|
|
452
|
+
const picks = [];
|
|
453
|
+
for (const badge of ['cheapest', 'fastest', 'best']) {
|
|
454
|
+
const card = cards.find((c) => c.badges.includes(badge));
|
|
455
|
+
if (!card)
|
|
456
|
+
continue;
|
|
457
|
+
picks.push({
|
|
458
|
+
badge,
|
|
459
|
+
label: flightBadgeLabel(badge),
|
|
460
|
+
key: card.key,
|
|
461
|
+
price: card.price,
|
|
462
|
+
duration: durationLabel(card.totalMinutes),
|
|
463
|
+
airline: card.airline,
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
// Every airport the offers leave from and land at, not the first offer's: New York results that
|
|
467
|
+
// land at LaGuardia and Newark read "ATL → LGA/EWR", never "ATL → LGA".
|
|
468
|
+
const airports = (pick) => {
|
|
469
|
+
const codes = [...new Set(cards.map((c) => pick(c.slices[0])).filter(Boolean))];
|
|
470
|
+
return codes.length <= 3 ? codes.join('/') : `${codes.slice(0, 2).join('/')} +${codes.length - 2}`;
|
|
471
|
+
};
|
|
472
|
+
return {
|
|
473
|
+
route: out
|
|
474
|
+
? `${airports((s) => s.origin)} ${roundTrip ? '⇄' : '→'} ${airports((s) => s.destination)}`
|
|
475
|
+
: undefined,
|
|
476
|
+
origin: out?.origin,
|
|
477
|
+
destination: out?.destination,
|
|
478
|
+
roundTrip,
|
|
479
|
+
date,
|
|
480
|
+
sameDate,
|
|
481
|
+
count: a.totalCount ?? cards.length,
|
|
482
|
+
fromPrice: cheapestCard?.price,
|
|
483
|
+
seller,
|
|
484
|
+
picks,
|
|
485
|
+
};
|
|
486
|
+
};export{airlineCode,airlineLogoUrl,airlineTone,cabinLabel,dateLabel,dayOffset,durationLabel,fareLineLabel,flightBadgeLabel,flightNumberLabel,flightPrice,flightPriceValue,flightResultSummary,isFlightAttachment,rankFlightCards,sortFlightCards,stopsLabel,toFlightCard,toFlightCards,wallClock};//# sourceMappingURL=flightCards.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flightCards.js","sources":["../../src/utils/flightCards.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;;;AAWG;AAEH,MAAA,UAAA,GAAA,kBAAA;AACA,MAAM,aAAW,GAAA,0BAAiB;
|
|
1
|
+
{"version":3,"file":"flightCards.js","sources":["../../src/utils/flightCards.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
|