atriusmaps-node-sdk 3.3.897 → 3.3.899
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/cjs/nodesdk/nodeEntry.js +36 -58
- package/dist/cjs/package.json.js +8 -4
- package/dist/cjs/plugins/clientAPI/src/clientAPI.js +8 -6
- package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +50 -142
- package/dist/cjs/plugins/dynamicPois/src/processors.js +31 -53
- package/dist/cjs/plugins/flightStatus/src/flightDetailsMapper.js +47 -116
- package/dist/cjs/plugins/flightStatus/src/flightStatus.js +48 -82
- package/dist/cjs/plugins/flightStatus/src/utils.js +4 -14
- package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +84 -154
- package/dist/cjs/plugins/sdkServer/src/prepareSDKConfig.js +45 -76
- package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +70 -79
- package/dist/cjs/plugins/sdkServer/src/sdkServer.js +97 -147
- package/dist/cjs/plugins/searchService/src/flexsearchExports/lang.js +16 -190
- package/dist/cjs/plugins/searchService/src/flexsearchExports/simple.js +28 -35
- package/dist/cjs/plugins/searchService/src/poiSearch.js +10 -21
- package/dist/cjs/plugins/searchService/src/searchService.js +45 -147
- package/dist/cjs/plugins/searchService/src/searchTypeahead.js +17 -28
- package/dist/cjs/plugins/searchService/src/utils.js +9 -13
- package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +148 -304
- package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +47 -126
- package/dist/cjs/plugins/wayfinder/src/findRoute.js +6 -73
- package/dist/cjs/plugins/wayfinder/src/minPriorityQueue.js +7 -27
- package/dist/cjs/plugins/wayfinder/src/navGraph.js +78 -259
- package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +26 -57
- package/dist/cjs/plugins/wayfinder/src/segmentBadges.js +25 -25
- package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +50 -133
- package/dist/cjs/plugins/wayfinder/src/segmentCategories.js +29 -29
- package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +53 -145
- package/dist/cjs/plugins/wayfinder/src/wayfinder.js +105 -349
- package/dist/cjs/src/app.js +53 -91
- package/dist/cjs/src/configs/postproc-mol-url-parms.js +34 -43
- package/dist/cjs/src/configs/postproc-stateTracking.js +1 -19
- package/dist/cjs/src/controller.js +4 -26
- package/dist/cjs/src/debugTools.js +55 -94
- package/dist/cjs/src/env.js +8 -19
- package/dist/cjs/src/extModules/bustle.js +15 -71
- package/dist/cjs/src/extModules/flexapi/src/help.js +7 -22
- package/dist/cjs/src/extModules/flexapi/src/index.js +15 -29
- package/dist/cjs/src/extModules/flexapi/src/validate.js +45 -93
- package/dist/cjs/src/extModules/geohasher.js +13 -31
- package/dist/cjs/src/extModules/log.js +18 -29
- package/dist/cjs/src/historyManager.js +4 -6
- package/dist/cjs/src/utils/bounds.js +2 -4
- package/dist/cjs/src/utils/buildStructureLookup.js +7 -7
- package/dist/cjs/src/utils/configUtils.js +7 -43
- package/dist/cjs/src/utils/date.js +5 -17
- package/dist/cjs/src/utils/distance.js +2 -2
- package/dist/cjs/src/utils/dom.js +9 -24
- package/dist/cjs/src/utils/funcs.js +15 -30
- package/dist/cjs/src/utils/geodesy.js +24 -39
- package/dist/cjs/src/utils/geom.js +32 -148
- package/dist/cjs/src/utils/i18n.js +39 -70
- package/dist/cjs/src/utils/isInitialState.js +7 -13
- package/dist/cjs/src/utils/location.js +10 -29
- package/dist/cjs/src/utils/observable.js +4 -29
- package/dist/cjs/src/utils/rand.js +9 -80
- package/dist/cjs/utils/constants.js +1 -1
- package/dist/package.json.js +1 -1
- package/dist/plugins/poiDataManager/src/poiDataManager.js +1 -1
- package/dist/plugins/sdkServer/src/prepareSDKConfig.js +1 -1
- package/dist/src/utils/buildStructureLookup.js +1 -1
- package/dist/src/utils/date.js +1 -1
- package/package.json +1 -1
|
@@ -6,11 +6,10 @@ var date = require('../../../src/utils/date.js');
|
|
|
6
6
|
var constants = require('../../../utils/constants.js');
|
|
7
7
|
|
|
8
8
|
const FlightType = {
|
|
9
|
-
ARRIVAL:
|
|
10
|
-
DEPARTURE:
|
|
11
|
-
ALL:
|
|
9
|
+
ARRIVAL: "arr",
|
|
10
|
+
DEPARTURE: "dep",
|
|
11
|
+
ALL: "all"
|
|
12
12
|
};
|
|
13
|
-
|
|
14
13
|
function mapFlightListItem(nowDate, flight, T, tz, locale) {
|
|
15
14
|
const {
|
|
16
15
|
flightId,
|
|
@@ -22,35 +21,29 @@ function mapFlightListItem(nowDate, flight, T, tz, locale) {
|
|
|
22
21
|
arrivalAirport,
|
|
23
22
|
airportResources,
|
|
24
23
|
gatePoi,
|
|
25
|
-
status: statusCode
|
|
24
|
+
status: statusCode
|
|
26
25
|
} = flight;
|
|
27
|
-
|
|
28
26
|
const rawDateTime = selectRawDateTime(flight);
|
|
29
|
-
const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz);
|
|
27
|
+
const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz);
|
|
30
28
|
const status = mapFlightStatus(flightType, statusCode, nowDate, localTime, localOldTime);
|
|
31
|
-
const datePlaceholder =
|
|
32
|
-
flightType === FlightType.DEPARTURE ? 'flightDetails:Departs _date_' : 'flightDetails:Arrives _date_';
|
|
33
|
-
|
|
29
|
+
const datePlaceholder = flightType === FlightType.DEPARTURE ? "flightDetails:Departs _date_" : "flightDetails:Arrives _date_";
|
|
34
30
|
return {
|
|
35
31
|
flightId,
|
|
36
|
-
name: `${R.propOr(
|
|
32
|
+
name: `${R.propOr("", "name", airline)} - ${carrierFsCode} ${flightNumber}`,
|
|
37
33
|
status,
|
|
38
34
|
statusText: T(`flightDetails:${getFlightStatusText(status)}`),
|
|
39
|
-
baggageClaim:
|
|
40
|
-
flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : undefined,
|
|
35
|
+
baggageClaim: flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : void 0,
|
|
41
36
|
connectionAirport: prepareAirportLabel(flightType, departureAirport, arrivalAirport, T),
|
|
42
37
|
time: getLocalFormattedTime(localTime, tz, locale),
|
|
43
38
|
oldTime: getLocalFormattedTime(localOldTime, tz, locale),
|
|
44
39
|
date: T(datePlaceholder, {
|
|
45
|
-
date: getLocalFormattedDate(localTime, tz, locale)
|
|
40
|
+
date: getLocalFormattedDate(localTime, tz, locale)
|
|
46
41
|
}),
|
|
47
42
|
dateStamp: localTime.toMillis(),
|
|
48
43
|
gate: formatGate(gatePoi),
|
|
49
|
-
gateLabel: T(
|
|
44
|
+
gateLabel: T("flightDetails:Gate")
|
|
50
45
|
};
|
|
51
46
|
}
|
|
52
|
-
|
|
53
|
-
// todo create test when airline is undefined
|
|
54
47
|
function mapFlightDetails(nowDate, flight, T, tz, locale) {
|
|
55
48
|
const {
|
|
56
49
|
flightNumber,
|
|
@@ -62,23 +55,20 @@ function mapFlightDetails(nowDate, flight, T, tz, locale) {
|
|
|
62
55
|
carrierFsCode,
|
|
63
56
|
gatePoi,
|
|
64
57
|
airline,
|
|
65
|
-
status: statusCode
|
|
58
|
+
status: statusCode
|
|
66
59
|
} = flight;
|
|
67
|
-
|
|
68
|
-
const pickAirportData = R.pick(['city', 'iata']);
|
|
60
|
+
const pickAirportData = R.pick(["city", "iata"]);
|
|
69
61
|
const rawDateTime = selectRawDateTime(flight);
|
|
70
|
-
const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz);
|
|
62
|
+
const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz);
|
|
71
63
|
const status = mapFlightStatus(flightType, statusCode, nowDate, localTime, localOldTime);
|
|
72
|
-
const flightTypeLabel = flightType === FlightType.DEPARTURE ?
|
|
73
|
-
|
|
64
|
+
const flightTypeLabel = flightType === FlightType.DEPARTURE ? "Departure" : "Arrival";
|
|
74
65
|
return {
|
|
75
66
|
flightType,
|
|
76
67
|
flightTypeLabel: T(`flightDetails:${flightTypeLabel}`),
|
|
77
|
-
name: `${R.propOr(
|
|
68
|
+
name: `${R.propOr("", "name", airline)} - ${carrierFsCode} ${flightNumber}`,
|
|
78
69
|
status,
|
|
79
70
|
statusText: T(`flightDetails:${getFlightStatusText(status)}`),
|
|
80
|
-
baggageClaim:
|
|
81
|
-
flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : undefined,
|
|
71
|
+
baggageClaim: flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : void 0,
|
|
82
72
|
departure: pickAirportData(departureAirport),
|
|
83
73
|
arrival: pickAirportData(arrivalAirport),
|
|
84
74
|
connectionAirport: prepareAirportLabel(flightType, departureAirport, arrivalAirport, T),
|
|
@@ -87,102 +77,72 @@ function mapFlightDetails(nowDate, flight, T, tz, locale) {
|
|
|
87
77
|
oldTime: getLocalFormattedTime(localOldTime, tz, locale),
|
|
88
78
|
date: getLocalFormattedDate(localTime, tz, locale),
|
|
89
79
|
lastUpdated: prepareLastUpdated(nowDate, flightStatusUpdates, T),
|
|
90
|
-
flightDuration:
|
|
91
|
-
gateLabel: T(
|
|
80
|
+
flightDuration: "",
|
|
81
|
+
gateLabel: T("flightDetails:Gate"),
|
|
92
82
|
gate: formatGate(gatePoi),
|
|
93
83
|
tags: [],
|
|
94
|
-
flightIconBaseName: flightType === FlightType.ARRIVAL ?
|
|
84
|
+
flightIconBaseName: flightType === FlightType.ARRIVAL ? "arrivals" : "departures"
|
|
95
85
|
};
|
|
96
86
|
}
|
|
97
|
-
|
|
98
|
-
// used to sort flights in ASCENDING order of flight arrival/departure time
|
|
99
87
|
const flightComparator = (flight1, flight2) => flight1.dateStamp - flight2.dateStamp;
|
|
100
|
-
|
|
101
|
-
// Matches gate identifiers: optional letter prefix + digits + optional letter suffix (e.g. "B54", "23", "B32a")
|
|
102
88
|
const gateNameRegex = /[A-Z]?\d+[a-zA-Z]?/;
|
|
103
|
-
|
|
104
|
-
const formatGate = gate => {
|
|
89
|
+
const formatGate = (gate) => {
|
|
105
90
|
if (!gate) {
|
|
106
|
-
return { name:
|
|
91
|
+
return { name: "-" };
|
|
107
92
|
}
|
|
108
93
|
const match = gate.name.match(gateNameRegex);
|
|
109
94
|
const name = match ? match[0] : gate.name;
|
|
110
95
|
return { ...gate, name };
|
|
111
96
|
};
|
|
112
|
-
|
|
113
97
|
const prepareFlightIn = (status, flightType, nowDate, flightDate, T) => {
|
|
114
98
|
if (status === constants.FlightLabelStatus.DEPARTED) {
|
|
115
|
-
return T(
|
|
99
|
+
return T("flightDetails:Departed");
|
|
116
100
|
} else if (status === constants.FlightLabelStatus.ARRIVED) {
|
|
117
|
-
return T(
|
|
101
|
+
return T("flightDetails:Arrived");
|
|
118
102
|
} else if (status === constants.FlightLabelStatus.CANCELLED) {
|
|
119
103
|
return null;
|
|
120
104
|
}
|
|
121
|
-
|
|
122
|
-
const prefix = flightType === FlightType.DEPARTURE ? 'Departs' : 'Arrives';
|
|
105
|
+
const prefix = flightType === FlightType.DEPARTURE ? "Departs" : "Arrives";
|
|
123
106
|
const minutes = minutesBetween(nowDate, flightDate);
|
|
124
107
|
return T(`flightDetails:${prefix} in _minutes_ minute`, { count: minutes });
|
|
125
108
|
};
|
|
126
|
-
|
|
127
109
|
const prepareLastUpdated = (nowDate, flightStatusUpdates, T) => {
|
|
128
|
-
const updateDate = R.compose(R.path([
|
|
110
|
+
const updateDate = R.compose(R.path(["updatedAt", "dateUtc"]), R.last)(flightStatusUpdates);
|
|
129
111
|
const minutes = minutesBetween(nowDate, getLocalGMTDate(updateDate));
|
|
130
|
-
|
|
131
112
|
if (minutes < 10) {
|
|
132
|
-
return T(
|
|
113
|
+
return T("flightDetails:Last updated a few minutes ago");
|
|
133
114
|
} else if (minutes < 60) {
|
|
134
|
-
return T(
|
|
115
|
+
return T("flightDetails:Last updated _minutes_ minutes ago", { minutes });
|
|
135
116
|
} else {
|
|
136
|
-
return T(
|
|
117
|
+
return T("flightDetails:Last updated over an hour ago");
|
|
137
118
|
}
|
|
138
119
|
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Check minutes difference between two Luxon dates.
|
|
142
|
-
* @param {DateTime} firstDate
|
|
143
|
-
* @param {DateTime} secondDate
|
|
144
|
-
*/
|
|
145
120
|
const minutesBetween = (firstDate, secondDate) => {
|
|
146
121
|
const ms = Math.abs(firstDate - secondDate);
|
|
147
122
|
return date.msToMin(ms);
|
|
148
123
|
};
|
|
149
|
-
|
|
150
|
-
const selectRawDateTime = ({ flightType, operationalTimes, departureDate, arrivalDate }) =>
|
|
151
|
-
flightType === FlightType.DEPARTURE
|
|
152
|
-
? prepareRawDateTime(departureDate, operationalTimes.estimatedGateDeparture)
|
|
153
|
-
: prepareRawDateTime(arrivalDate, operationalTimes.estimatedGateArrival);
|
|
154
|
-
|
|
124
|
+
const selectRawDateTime = ({ flightType, operationalTimes, departureDate, arrivalDate }) => flightType === FlightType.DEPARTURE ? prepareRawDateTime(departureDate, operationalTimes.estimatedGateDeparture) : prepareRawDateTime(arrivalDate, operationalTimes.estimatedGateArrival);
|
|
155
125
|
const prepareRawDateTime = (dateTime, estimatedTime) => {
|
|
156
126
|
const localDate = dateTime.dateLocal || dateTime.dateUtc;
|
|
157
127
|
const estimatedDate = estimatedTime.dateLocal || estimatedTime.dateUtc;
|
|
158
128
|
const isTimeChanged = estimatedDate && localDate !== estimatedDate;
|
|
159
129
|
return isTimeChanged ? { time: estimatedDate, oldTime: localDate } : { time: localDate };
|
|
160
130
|
};
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Parse flight dates strings to Luxon dates relative to the venue timezone.
|
|
164
|
-
* @param {{ time: string, oldTime: string }} - times
|
|
165
|
-
* @param {string} tz - venue timezone
|
|
166
|
-
*/
|
|
167
131
|
const formatToLocalDateTimes = ({ time, oldTime }, tz) => ({
|
|
168
132
|
localTime: getLocalGMTDate(time, tz),
|
|
169
|
-
localOldTime: getLocalGMTDate(oldTime, tz)
|
|
133
|
+
localOldTime: getLocalGMTDate(oldTime, tz)
|
|
170
134
|
});
|
|
171
|
-
|
|
172
135
|
function mapFlightStatus(flightType, status, nowDate, localTime, localOldTime) {
|
|
173
136
|
if (!localTime) {
|
|
174
137
|
return constants.FlightLabelStatus.UNKNOWN;
|
|
175
138
|
}
|
|
176
|
-
|
|
177
139
|
if (nowDate > localTime) {
|
|
178
140
|
return lateFlightStatus(flightType);
|
|
179
141
|
}
|
|
180
|
-
|
|
181
142
|
status = status.toUpperCase();
|
|
182
|
-
if (status ===
|
|
143
|
+
if (status === "C") {
|
|
183
144
|
return constants.FlightLabelStatus.CANCELLED;
|
|
184
145
|
}
|
|
185
|
-
|
|
186
146
|
if (!localOldTime) {
|
|
187
147
|
return constants.FlightLabelStatus.ON_TIME;
|
|
188
148
|
} else if (localTime > localOldTime) {
|
|
@@ -191,62 +151,33 @@ function mapFlightStatus(flightType, status, nowDate, localTime, localOldTime) {
|
|
|
191
151
|
return constants.FlightLabelStatus.EARLY;
|
|
192
152
|
}
|
|
193
153
|
}
|
|
194
|
-
|
|
195
|
-
const getFlightStatusText = status => {
|
|
154
|
+
const getFlightStatusText = (status) => {
|
|
196
155
|
switch (status) {
|
|
197
156
|
case constants.FlightLabelStatus.ON_TIME:
|
|
198
|
-
return
|
|
157
|
+
return "on-time";
|
|
199
158
|
case constants.FlightLabelStatus.EARLY:
|
|
200
|
-
return
|
|
159
|
+
return "early";
|
|
201
160
|
case constants.FlightLabelStatus.DELAYED:
|
|
202
|
-
return
|
|
161
|
+
return "delayed";
|
|
203
162
|
case constants.FlightLabelStatus.CANCELLED:
|
|
204
|
-
return
|
|
163
|
+
return "cancelled";
|
|
205
164
|
case constants.FlightLabelStatus.DEPARTED:
|
|
206
|
-
return
|
|
165
|
+
return "departed";
|
|
207
166
|
case constants.FlightLabelStatus.ARRIVED:
|
|
208
|
-
return
|
|
167
|
+
return "arrived";
|
|
209
168
|
default:
|
|
210
|
-
return
|
|
169
|
+
return "unknown";
|
|
211
170
|
}
|
|
212
171
|
};
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
? T(formatAirportLabel('To'), arrivalAirport)
|
|
220
|
-
: T(formatAirportLabel('From'), departureAirport);
|
|
221
|
-
|
|
222
|
-
const formatAirportLabel = prefix => `flightDetails:${prefix} _city_ (_iata_)`;
|
|
223
|
-
|
|
224
|
-
const prepareBaggageClaim = (claimNum, T) =>
|
|
225
|
-
claimNum &&
|
|
226
|
-
T('flightDetails:Collect luggage from Baggage Claim _claimNum_', {
|
|
227
|
-
claimNum,
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Parse date string to Luxon date relative to the venue timezone.
|
|
232
|
-
* @param {string} date string (can be UTC)
|
|
233
|
-
* @param {string} tz - venue timezone
|
|
234
|
-
*/
|
|
172
|
+
const lateFlightStatus = (flightType) => flightType === FlightType.DEPARTURE ? constants.FlightLabelStatus.DEPARTED : constants.FlightLabelStatus.ARRIVED;
|
|
173
|
+
const prepareAirportLabel = (flightType, departureAirport, arrivalAirport, T) => flightType === FlightType.DEPARTURE ? T(formatAirportLabel("To"), arrivalAirport) : T(formatAirportLabel("From"), departureAirport);
|
|
174
|
+
const formatAirportLabel = (prefix) => `flightDetails:${prefix} _city_ (_iata_)`;
|
|
175
|
+
const prepareBaggageClaim = (claimNum, T) => claimNum && T("flightDetails:Collect luggage from Baggage Claim _claimNum_", {
|
|
176
|
+
claimNum
|
|
177
|
+
});
|
|
235
178
|
const getLocalGMTDate = (date, tz) => date && luxon.DateTime.fromISO(date, { zone: tz });
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
dateStr && luxon.DateTime.fromISO(dateStr, { zone: tz }).setLocale(locale).toFormat('EEE, d MMMM');
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Parse date string to Luxon date in venue timezone and return short time.
|
|
242
|
-
* Set locale, so the returned time can match the format used in particular locale.
|
|
243
|
-
* E.g. for 'en-US' it will return "6:00 AM". For 'fr' it will return "6:00".
|
|
244
|
-
* @param {string} dateStr - date string (can be UTC)
|
|
245
|
-
* @param {string} tz - timezone string
|
|
246
|
-
* @param {string} [locale='en-US'] locale string
|
|
247
|
-
*/
|
|
248
|
-
const getLocalFormattedTime = (dateStr, tz, locale = 'en-US') =>
|
|
249
|
-
dateStr && date.formatTime(luxon.DateTime.fromISO(dateStr, { zone: tz }), locale);
|
|
179
|
+
const getLocalFormattedDate = (dateStr, tz, locale = "en-US") => dateStr && luxon.DateTime.fromISO(dateStr, { zone: tz }).setLocale(locale).toFormat("EEE, d MMMM");
|
|
180
|
+
const getLocalFormattedTime = (dateStr, tz, locale = "en-US") => dateStr && date.formatTime(luxon.DateTime.fromISO(dateStr, { zone: tz }), locale);
|
|
250
181
|
|
|
251
182
|
exports.FlightType = FlightType;
|
|
252
183
|
exports.flightComparator = flightComparator;
|
|
@@ -26,40 +26,31 @@ function _interopNamespaceDefault(e) {
|
|
|
26
26
|
var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
|
|
27
27
|
|
|
28
28
|
function create(app, config) {
|
|
29
|
-
const createIndex = () =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
29
|
+
const createIndex = () => new FlexSearch.Index({
|
|
30
|
+
tokenize: "forward"
|
|
31
|
+
});
|
|
33
32
|
const init = async () => {
|
|
34
|
-
state.tz = await app.bus.get(
|
|
33
|
+
state.tz = await app.bus.get("venueData/getVenueTimezone");
|
|
35
34
|
};
|
|
36
|
-
|
|
37
35
|
const state = {
|
|
38
36
|
lastUpdated: 0,
|
|
39
37
|
flights: { dep: null, arr: null },
|
|
40
38
|
index: { dep: createIndex(), arr: createIndex() },
|
|
41
39
|
gates: null,
|
|
42
|
-
apiError: false
|
|
40
|
+
apiError: false
|
|
43
41
|
};
|
|
44
|
-
|
|
45
42
|
const enrichData = (flights, airportsArg, airlinesArg, flightType) => {
|
|
46
43
|
const airports = airportsArg.reduce((acc, obj) => {
|
|
47
44
|
return { ...acc, [obj.iata]: obj };
|
|
48
45
|
}, {});
|
|
49
|
-
const airlines = airlinesArg
|
|
50
|
-
.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}, {});
|
|
58
|
-
return flights.map(flight => {
|
|
59
|
-
const gateId =
|
|
60
|
-
flightType === flightDetailsMapper.FlightType.DEPARTURE
|
|
61
|
-
? R__namespace.pathOr('', ['airportResources', 'departureGate'], flight)
|
|
62
|
-
: R__namespace.pathOr('', ['airportResources', 'arrivalGate'], flight);
|
|
46
|
+
const airlines = airlinesArg.flatMap((airline) => [
|
|
47
|
+
{ code: airline.iata, airline },
|
|
48
|
+
{ code: airline.icao, airline }
|
|
49
|
+
]).filter(({ code }) => code).reduce((acc, { code, airline }) => {
|
|
50
|
+
return { ...acc, [code]: airline };
|
|
51
|
+
}, {});
|
|
52
|
+
return flights.map((flight) => {
|
|
53
|
+
const gateId = flightType === flightDetailsMapper.FlightType.DEPARTURE ? R__namespace.pathOr("", ["airportResources", "departureGate"], flight) : R__namespace.pathOr("", ["airportResources", "arrivalGate"], flight);
|
|
63
54
|
const gatePoi = state.gates[gateId];
|
|
64
55
|
return {
|
|
65
56
|
...flight,
|
|
@@ -67,90 +58,84 @@ function create(app, config) {
|
|
|
67
58
|
gatePoi,
|
|
68
59
|
airline: airlines[flight.carrierFsCode],
|
|
69
60
|
departureAirport: airports[flight.departureAirportFsCode],
|
|
70
|
-
arrivalAirport: airports[flight.arrivalAirportFsCode]
|
|
61
|
+
arrivalAirport: airports[flight.arrivalAirportFsCode]
|
|
71
62
|
};
|
|
72
63
|
});
|
|
73
64
|
};
|
|
74
|
-
|
|
75
65
|
const updateIndexes = (type, flightStatuses) => {
|
|
76
66
|
state.index[type] = createIndex();
|
|
77
67
|
state.flights[type] = {};
|
|
78
|
-
flightStatuses.forEach(status => {
|
|
68
|
+
flightStatuses.forEach((status) => {
|
|
79
69
|
state.index[type].add(status.flightId, createFlightSearchEntry(status));
|
|
80
70
|
state.flights[type][status.flightId] = status;
|
|
81
71
|
});
|
|
82
72
|
};
|
|
83
|
-
|
|
84
73
|
const searchPropertiesPaths = [
|
|
85
|
-
[
|
|
86
|
-
[
|
|
87
|
-
[
|
|
88
|
-
[
|
|
89
|
-
[
|
|
90
|
-
[
|
|
91
|
-
[
|
|
74
|
+
["flightNumber"],
|
|
75
|
+
["airline", "iata"],
|
|
76
|
+
["airline", "name"],
|
|
77
|
+
["arrivalAirport", "iata"],
|
|
78
|
+
["arrivalAirport", "city"],
|
|
79
|
+
["departureAirport", "iata"],
|
|
80
|
+
["departureAirport", "city"]
|
|
92
81
|
];
|
|
93
82
|
const createFlightSearchEntry = R__namespace.pipe(
|
|
94
83
|
// apply each function one after another to passed object
|
|
95
|
-
R__namespace.juxt(R__namespace.map(R__namespace.path, searchPropertiesPaths)),
|
|
96
|
-
|
|
97
|
-
R__namespace.
|
|
84
|
+
R__namespace.juxt(R__namespace.map(R__namespace.path, searchPropertiesPaths)),
|
|
85
|
+
// safe collect of nested properties into list
|
|
86
|
+
R__namespace.filter(R__namespace.identity),
|
|
87
|
+
// filter 'falsy' values
|
|
88
|
+
R__namespace.join(" ")
|
|
98
89
|
);
|
|
99
|
-
|
|
100
90
|
const indexGatePois = async () => {
|
|
101
91
|
if (state.gates === null) {
|
|
102
|
-
const gatePois = await app.bus.get(
|
|
103
|
-
categoryId:
|
|
92
|
+
const gatePois = await app.bus.get("poi/getByCategoryId", {
|
|
93
|
+
categoryId: "gate"
|
|
104
94
|
});
|
|
105
|
-
const parseGate = ({ name }) => R__namespace.tail(name.replace(
|
|
95
|
+
const parseGate = ({ name }) => R__namespace.tail(name.replace(",", "").split(" "));
|
|
106
96
|
const pairs = R__namespace.reduce(
|
|
107
97
|
(acc, poi) => {
|
|
108
98
|
const gateIds = parseGate(poi);
|
|
109
|
-
const gateAndPoiPairs = R__namespace.map(gateId => [gateId, poi], gateIds);
|
|
99
|
+
const gateAndPoiPairs = R__namespace.map((gateId) => [gateId, poi], gateIds);
|
|
110
100
|
return [...acc, ...gateAndPoiPairs];
|
|
111
101
|
},
|
|
112
102
|
[],
|
|
113
|
-
Object.values(gatePois)
|
|
103
|
+
Object.values(gatePois)
|
|
114
104
|
);
|
|
115
|
-
|
|
116
105
|
state.gates = R__namespace.fromPairs(pairs);
|
|
117
106
|
}
|
|
118
107
|
return state;
|
|
119
108
|
};
|
|
120
|
-
|
|
121
109
|
const updateFlights = async () => {
|
|
122
110
|
await indexGatePois();
|
|
123
|
-
const venueData = await app.bus.get(
|
|
111
|
+
const venueData = await app.bus.get("venueData/getVenueData");
|
|
124
112
|
const params = new URLSearchParams();
|
|
125
113
|
const locale = app.i18n?.().language;
|
|
126
114
|
if (locale) {
|
|
127
|
-
params.append(
|
|
115
|
+
params.append("locale", locale);
|
|
128
116
|
}
|
|
129
117
|
if (config?.timeRange) {
|
|
130
118
|
const now = Date.now();
|
|
131
119
|
const startDate = new Date(now - config.timeRange.beforeNowMs).toISOString();
|
|
132
120
|
const endDate = new Date(now + config.timeRange.afterNowMs).toISOString();
|
|
133
|
-
params.append(
|
|
134
|
-
params.append(
|
|
121
|
+
params.append("startDate", startDate);
|
|
122
|
+
params.append("endDate", endDate);
|
|
135
123
|
}
|
|
136
|
-
|
|
137
124
|
const baseURL = `https://marketplace.locuslabs.com/venueId/${venueData.baseVenueId}/flight-status`;
|
|
138
125
|
const apiURL = params.toString() ? `${baseURL}?${params.toString()}` : baseURL;
|
|
139
|
-
|
|
140
126
|
try {
|
|
141
127
|
const response = await fetch(apiURL);
|
|
142
128
|
const data = await response.json();
|
|
143
|
-
[flightDetailsMapper.FlightType.ARRIVAL, flightDetailsMapper.FlightType.DEPARTURE].forEach(type => {
|
|
144
|
-
const key = type === flightDetailsMapper.FlightType.DEPARTURE ?
|
|
129
|
+
[flightDetailsMapper.FlightType.ARRIVAL, flightDetailsMapper.FlightType.DEPARTURE].forEach((type) => {
|
|
130
|
+
const key = type === flightDetailsMapper.FlightType.DEPARTURE ? "departures" : "arrivals";
|
|
145
131
|
const { airports, airlines } = data.data[key].appendix;
|
|
146
132
|
updateIndexes(type, enrichData(data.data[key].flightStatuses, airports, airlines, type));
|
|
147
133
|
});
|
|
148
134
|
state.apiError = false;
|
|
149
135
|
} catch (error) {
|
|
150
136
|
state.apiError = true;
|
|
151
|
-
console.error(
|
|
152
|
-
[flightDetailsMapper.FlightType.ARRIVAL, flightDetailsMapper.FlightType.DEPARTURE].forEach(type => {
|
|
153
|
-
// In the case of an api error we still need to update current flights to an empty array, otherwise we get an object undefined error
|
|
137
|
+
console.error("Error from flight status api call", error);
|
|
138
|
+
[flightDetailsMapper.FlightType.ARRIVAL, flightDetailsMapper.FlightType.DEPARTURE].forEach((type) => {
|
|
154
139
|
updateIndexes(type, []);
|
|
155
140
|
});
|
|
156
141
|
} finally {
|
|
@@ -158,51 +143,32 @@ function create(app, config) {
|
|
|
158
143
|
}
|
|
159
144
|
return state;
|
|
160
145
|
};
|
|
161
|
-
|
|
162
146
|
const checkFlights = async () => {
|
|
163
|
-
|
|
164
|
-
if (Date.now() - state.lastUpdated > 60 * 1000) {
|
|
147
|
+
if (Date.now() - state.lastUpdated > 60 * 1e3) {
|
|
165
148
|
await updateFlights();
|
|
166
149
|
}
|
|
167
150
|
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Does query for flight status info. Before doing anything requests verification
|
|
171
|
-
* if the date is up-to-date
|
|
172
|
-
* @param {String} term - term to query the search index, default null, if null returns all flights of provided type
|
|
173
|
-
* @param {String} type - type of flights to query for, default 'dep' (departures)
|
|
174
|
-
*/
|
|
175
|
-
app.bus.on('flightStatus/query', async ({ term = null, type = flightDetailsMapper.FlightType.DEPARTURE } = {}) => {
|
|
151
|
+
app.bus.on("flightStatus/query", async ({ term = null, type = flightDetailsMapper.FlightType.DEPARTURE } = {}) => {
|
|
176
152
|
await checkFlights();
|
|
177
153
|
return utils.searchFlights(term, type, state);
|
|
178
154
|
});
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Fetches flight info based on flight ID, make sure the data is up-tp-date first
|
|
182
|
-
* @param {String} flightId - id of the flight we want to get
|
|
183
|
-
*/
|
|
184
|
-
app.bus.on('flightStatus/getFlight', async ({ flightId }) => {
|
|
155
|
+
app.bus.on("flightStatus/getFlight", async ({ flightId }) => {
|
|
185
156
|
await checkFlights();
|
|
186
157
|
const flight = state.flights.dep[flightId] || state.flights.arr[flightId];
|
|
187
158
|
return flight;
|
|
188
159
|
});
|
|
189
|
-
|
|
190
|
-
app.bus.on('flightStatus/mapFlightDetails', async ({ flight }) => {
|
|
160
|
+
app.bus.on("flightStatus/mapFlightDetails", async ({ flight }) => {
|
|
191
161
|
return flightDetailsMapper.mapFlightDetails(luxon.DateTime.local(), flight, app.gt(), state.tz, app.i18n().language);
|
|
192
162
|
});
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return flights
|
|
196
|
-
.map(flight => flightDetailsMapper.mapFlightListItem(luxon.DateTime.local(), flight, app.gt(), state.tz, app.i18n().language))
|
|
197
|
-
.sort(flightDetailsMapper.flightComparator);
|
|
163
|
+
app.bus.on("flightStatus/mapFlightListItems", async ({ flights }) => {
|
|
164
|
+
return flights.map((flight) => flightDetailsMapper.mapFlightListItem(luxon.DateTime.local(), flight, app.gt(), state.tz, app.i18n().language)).sort(flightDetailsMapper.flightComparator);
|
|
198
165
|
});
|
|
199
|
-
|
|
200
166
|
return {
|
|
201
167
|
init,
|
|
202
168
|
internal: {
|
|
203
169
|
updateFlights,
|
|
204
|
-
indexGatePois
|
|
205
|
-
}
|
|
170
|
+
indexGatePois
|
|
171
|
+
}
|
|
206
172
|
};
|
|
207
173
|
}
|
|
208
174
|
|
|
@@ -2,30 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
var flightDetailsMapper = require('./flightDetailsMapper.js');
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Searches flights by term or returns all flights of specified type(s)
|
|
7
|
-
* @param {String} term - Search term, or null to return all flights
|
|
8
|
-
* @param {String} type - Flight type: 'dep', 'arr', or 'all'
|
|
9
|
-
* @param {Object} state - Flight state object { index, flights, apiError }
|
|
10
|
-
* @returns {Object} { flights: Array, apiError: Boolean }
|
|
11
|
-
*/
|
|
12
5
|
const searchFlights = (term, type, state) => {
|
|
13
6
|
const { index, flights, apiError } = state;
|
|
14
7
|
const types = type === flightDetailsMapper.FlightType.ALL ? [flightDetailsMapper.FlightType.DEPARTURE, flightDetailsMapper.FlightType.ARRIVAL] : [type];
|
|
15
|
-
|
|
16
8
|
let flightResults;
|
|
17
9
|
if (term) {
|
|
18
|
-
flightResults = types.flatMap(t => {
|
|
10
|
+
flightResults = types.flatMap((t) => {
|
|
19
11
|
const ids = index[t].search({ query: term });
|
|
20
|
-
return ids.map(id => flights[t][id]);
|
|
12
|
+
return ids.map((id) => flights[t][id]);
|
|
21
13
|
});
|
|
22
14
|
} else {
|
|
23
|
-
flightResults = types.flatMap(t => Object.values(flights[t]));
|
|
15
|
+
flightResults = types.flatMap((t) => Object.values(flights[t]));
|
|
24
16
|
}
|
|
25
|
-
|
|
26
17
|
if (flightResults.length === 0 && /^\w\w\d{2,4}$/.test(term)) {
|
|
27
|
-
|
|
28
|
-
const modifiedTerm = term.replace(/(\w\w)(\d{2,4})/, '$1_$2');
|
|
18
|
+
const modifiedTerm = term.replace(/(\w\w)(\d{2,4})/, "$1_$2");
|
|
29
19
|
return searchFlights(modifiedTerm, type, state);
|
|
30
20
|
}
|
|
31
21
|
return { flights: flightResults, apiError };
|