atriusmaps-node-sdk
Version:
This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information
189 lines (185 loc) • 8.18 kB
JavaScript
;
var luxon = require('luxon');
var R = require('ramda');
var date = require('../../../src/utils/date.js');
var constants = require('../../../utils/constants.js');
const FlightType = {
ARRIVAL: "arr",
DEPARTURE: "dep",
ALL: "all"
};
function mapFlightListItem(nowDate, flight, T, tz, locale) {
const {
flightId,
carrierFsCode,
flightNumber,
airline,
flightType,
departureAirport,
arrivalAirport,
airportResources,
gatePoi,
status: statusCode
} = flight;
const rawDateTime = selectRawDateTime(flight);
const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz);
const status = mapFlightStatus(flightType, statusCode, nowDate, localTime, localOldTime);
const datePlaceholder = flightType === FlightType.DEPARTURE ? "flightDetails:Departs _date_" : "flightDetails:Arrives _date_";
return {
flightId,
name: `${R.propOr("", "name", airline)} - ${carrierFsCode} ${flightNumber}`,
status,
statusText: T(`flightDetails:${getFlightStatusText(status)}`),
baggageClaim: flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : void 0,
connectionAirport: prepareAirportLabel(flightType, departureAirport, arrivalAirport, T),
time: getLocalFormattedTime(localTime?.toISO() ?? null, tz, locale),
oldTime: getLocalFormattedTime(localOldTime?.toISO() ?? null, tz, locale),
date: T(datePlaceholder, {
date: getLocalFormattedDate(localTime?.toISO() ?? null, tz, locale)
}),
dateStamp: localTime?.toMillis() ?? 0,
gate: formatGate(gatePoi),
gateLabel: T("flightDetails:Gate")
};
}
function mapFlightDetails(nowDate, flight, T, tz, locale) {
const {
flightNumber,
flightType,
departureAirport,
arrivalAirport,
airportResources,
flightStatusUpdates,
carrierFsCode,
gatePoi,
airline,
status: statusCode
} = flight;
const pickAirportData = R.pick(["city", "iata"]);
const rawDateTime = selectRawDateTime(flight);
const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz);
const status = mapFlightStatus(flightType, statusCode, nowDate, localTime, localOldTime);
const flightTypeLabel = flightType === FlightType.DEPARTURE ? "Departure" : "Arrival";
return {
flightType,
flightTypeLabel: T(`flightDetails:${flightTypeLabel}`),
name: `${R.propOr("", "name", airline)} - ${carrierFsCode} ${flightNumber}`,
status,
statusText: T(`flightDetails:${getFlightStatusText(status)}`),
baggageClaim: flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : void 0,
departure: pickAirportData(departureAirport),
arrival: pickAirportData(arrivalAirport),
connectionAirport: prepareAirportLabel(flightType, departureAirport, arrivalAirport, T),
flightIn: prepareFlightIn(status, flightType, nowDate, localTime, T),
time: getLocalFormattedTime(localTime?.toISO() ?? null, tz, locale),
oldTime: getLocalFormattedTime(localOldTime?.toISO() ?? null, tz, locale),
date: getLocalFormattedDate(localTime?.toISO() ?? null, tz, locale),
lastUpdated: prepareLastUpdated(nowDate, flightStatusUpdates ?? [], T),
flightDuration: "",
gateLabel: T("flightDetails:Gate"),
gate: formatGate(gatePoi),
tags: [],
flightIconBaseName: flightType === FlightType.ARRIVAL ? "arrivals" : "departures"
};
}
const flightComparator = (flight1, flight2) => flight1.dateStamp - flight2.dateStamp;
const gateNameRegex = /[A-Z]?\d+[a-zA-Z]?/;
const formatGate = (gate) => {
if (!gate) {
return { name: "-" };
}
const match = gate.name.match(gateNameRegex);
return { ...gate, name: match ? match[0] : gate.name };
};
const prepareFlightIn = (status, flightType, nowDate, flightDate, T) => {
if (status === constants.FlightLabelStatus.DEPARTED) {
return T("flightDetails:Departed");
}
if (status === constants.FlightLabelStatus.ARRIVED) {
return T("flightDetails:Arrived");
}
if (status === constants.FlightLabelStatus.CANCELLED) {
return null;
}
if (!flightDate) {
return null;
}
const prefix = flightType === FlightType.DEPARTURE ? "Departs" : "Arrives";
return T(`flightDetails:${prefix} in _minutes_ minute`, { count: minutesBetween(nowDate, flightDate) });
};
const prepareLastUpdated = (nowDate, flightStatusUpdates, T) => {
const updateDate = R.compose(R.path(["updatedAt", "dateUtc"]), R.last)(flightStatusUpdates);
const localUpdateDate = getLocalGMTDate(updateDate);
if (!localUpdateDate) {
return T("flightDetails:Last updated a few minutes ago");
}
const minutes = minutesBetween(nowDate, localUpdateDate);
if (minutes < 10) {
return T("flightDetails:Last updated a few minutes ago");
}
if (minutes < 60) {
return T("flightDetails:Last updated _minutes_ minutes ago", { minutes });
}
return T("flightDetails:Last updated over an hour ago");
};
const minutesBetween = (firstDate, secondDate) => date.msToMin(Math.abs(firstDate.toMillis() - secondDate.toMillis()));
const selectRawDateTime = ({ flightType, operationalTimes, departureDate, arrivalDate }) => flightType === FlightType.DEPARTURE ? prepareRawDateTime(departureDate, operationalTimes.estimatedGateDeparture) : prepareRawDateTime(arrivalDate, operationalTimes.estimatedGateArrival);
const prepareRawDateTime = (dateTime, estimatedTime) => {
const localDate = dateTime.dateLocal || dateTime.dateUtc;
const estimatedDate = estimatedTime?.dateLocal || estimatedTime?.dateUtc;
return estimatedDate && localDate !== estimatedDate ? { time: estimatedDate, oldTime: localDate } : { time: localDate };
};
const formatToLocalDateTimes = ({ time, oldTime }, tz) => ({
localTime: getLocalGMTDate(time, tz),
localOldTime: getLocalGMTDate(oldTime, tz)
});
function mapFlightStatus(flightType, status, nowDate, localTime, localOldTime) {
if (!localTime) {
return constants.FlightLabelStatus.UNKNOWN;
}
if (nowDate > localTime) {
return lateFlightStatus(flightType);
}
const normalizedStatus = status.toUpperCase();
if (normalizedStatus === "C") {
return constants.FlightLabelStatus.CANCELLED;
}
if (!localOldTime) {
return constants.FlightLabelStatus.ON_TIME;
}
if (localTime > localOldTime) {
return constants.FlightLabelStatus.DELAYED;
}
return constants.FlightLabelStatus.EARLY;
}
const getFlightStatusText = (status) => {
switch (status) {
case constants.FlightLabelStatus.ON_TIME:
return "on-time";
case constants.FlightLabelStatus.EARLY:
return "early";
case constants.FlightLabelStatus.DELAYED:
return "delayed";
case constants.FlightLabelStatus.CANCELLED:
return "cancelled";
case constants.FlightLabelStatus.DEPARTED:
return "departed";
case constants.FlightLabelStatus.ARRIVED:
return "arrived";
default:
return "unknown";
}
};
const lateFlightStatus = (flightType) => flightType === FlightType.DEPARTURE ? constants.FlightLabelStatus.DEPARTED : constants.FlightLabelStatus.ARRIVED;
const prepareAirportLabel = (flightType, departureAirport, arrivalAirport, T) => flightType === FlightType.DEPARTURE ? T(formatAirportLabel("To"), arrivalAirport ?? {}) : T(formatAirportLabel("From"), departureAirport ?? {});
const formatAirportLabel = (prefix) => `flightDetails:${prefix} _city_ (_iata_)`;
const prepareBaggageClaim = (claimNum, T) => claimNum ? T("flightDetails:Collect luggage from Baggage Claim _claimNum_", { claimNum }) : null;
const getLocalGMTDate = (date, tz) => date ? luxon.DateTime.fromISO(date, { zone: tz }) : null;
const getLocalFormattedDate = (dateStr, tz, locale = "en-US") => dateStr ? luxon.DateTime.fromISO(dateStr, { zone: tz }).setLocale(locale).toFormat("EEE, d MMMM") : null;
const getLocalFormattedTime = (dateStr, tz, locale = "en-US") => dateStr ? date.formatTime(luxon.DateTime.fromISO(dateStr, { zone: tz }), locale) : null;
exports.FlightType = FlightType;
exports.flightComparator = flightComparator;
exports.formatGate = formatGate;
exports.gateNameRegex = gateNameRegex;
exports.mapFlightDetails = mapFlightDetails;
exports.mapFlightListItem = mapFlightListItem;