UNPKG

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
'use strict'; 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;