atriusmaps-node-sdk 3.3.834 → 3.3.836

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.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var name = "web-engine";
6
- var version = "3.3.834";
6
+ var version = "3.3.836";
7
7
  var license = "UNLICENSED";
8
8
  var type = "module";
9
9
  var main = "src/main.js";
@@ -0,0 +1,250 @@
1
+ 'use strict';
2
+
3
+ var luxon = require('luxon');
4
+ var R = require('ramda');
5
+ var date = require('../../../src/utils/date.js');
6
+ var constants = require('../../../utils/constants.js');
7
+
8
+ const FlightType = {
9
+ ARRIVAL: 'arr',
10
+ DEPARTURE: 'dep',
11
+ ALL: 'all',
12
+ };
13
+
14
+ function mapFlightListItem(nowDate, flight, T, tz, locale) {
15
+ const {
16
+ flightId,
17
+ carrierFsCode,
18
+ flightNumber,
19
+ airline,
20
+ flightType,
21
+ departureAirport,
22
+ arrivalAirport,
23
+ airportResources,
24
+ gatePoi,
25
+ status: statusCode,
26
+ } = flight;
27
+
28
+ const rawDateTime = selectRawDateTime(flight);
29
+ const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz); // local refers to the venue time
30
+ const status = mapFlightStatus(flightType, statusCode, nowDate, localTime, localOldTime);
31
+ const datePlaceholder =
32
+ flightType === FlightType.DEPARTURE ? 'flightDetails:Departs _date_' : 'flightDetails:Arrives _date_';
33
+
34
+ return {
35
+ flightId,
36
+ name: `${R.propOr('', 'name', airline)} - ${carrierFsCode} ${flightNumber}`,
37
+ status,
38
+ statusText: T(`flightDetails:${getFlightStatusText(status)}`),
39
+ baggageClaim:
40
+ flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : undefined,
41
+ connectionAirport: prepareAirportLabel(flightType, departureAirport, arrivalAirport, T),
42
+ time: getLocalFormattedTime(localTime, tz, locale),
43
+ oldTime: getLocalFormattedTime(localOldTime, tz, locale),
44
+ date: T(datePlaceholder, {
45
+ date: getLocalFormattedDate(localTime, tz, locale),
46
+ }),
47
+ dateStamp: localTime.toMillis(),
48
+ gate: formatGate(gatePoi),
49
+ gateLabel: T('flightDetails:Gate'),
50
+ };
51
+ }
52
+
53
+ // todo create test when airline is undefined
54
+ function mapFlightDetails(nowDate, flight, T, tz, locale) {
55
+ const {
56
+ flightNumber,
57
+ flightType,
58
+ departureAirport,
59
+ arrivalAirport,
60
+ airportResources,
61
+ flightStatusUpdates,
62
+ carrierFsCode,
63
+ gatePoi,
64
+ airline,
65
+ status: statusCode,
66
+ } = flight;
67
+
68
+ const pickAirportData = R.pick(['city', 'iata']);
69
+ const rawDateTime = selectRawDateTime(flight);
70
+ const { localTime, localOldTime } = formatToLocalDateTimes(rawDateTime, tz); // local refers to the venue time
71
+ const status = mapFlightStatus(flightType, statusCode, nowDate, localTime, localOldTime);
72
+ const flightTypeLabel = flightType === FlightType.DEPARTURE ? 'Departure' : 'Arrival';
73
+
74
+ return {
75
+ flightType,
76
+ flightTypeLabel: T(`flightDetails:${flightTypeLabel}`),
77
+ name: `${R.propOr('', 'name', airline)} - ${carrierFsCode} ${flightNumber}`,
78
+ status,
79
+ statusText: T(`flightDetails:${getFlightStatusText(status)}`),
80
+ baggageClaim:
81
+ flightType === FlightType.ARRIVAL ? prepareBaggageClaim(airportResources.arrivalBagClaim, T) : undefined,
82
+ departure: pickAirportData(departureAirport),
83
+ arrival: pickAirportData(arrivalAirport),
84
+ connectionAirport: prepareAirportLabel(flightType, departureAirport, arrivalAirport, T),
85
+ flightIn: prepareFlightIn(status, flightType, nowDate, localTime, T),
86
+ time: getLocalFormattedTime(localTime, tz, locale),
87
+ oldTime: getLocalFormattedTime(localOldTime, tz, locale),
88
+ date: getLocalFormattedDate(localTime, tz, locale),
89
+ lastUpdated: prepareLastUpdated(nowDate, flightStatusUpdates, T),
90
+ flightDuration: '',
91
+ gateLabel: T('flightDetails:Gate'),
92
+ gate: formatGate(gatePoi),
93
+ tags: [],
94
+ flightIconBaseName: flightType === FlightType.ARRIVAL ? 'arrivals' : 'departures',
95
+ };
96
+ }
97
+
98
+ // used to sort flights in ASCENDING order of flight arrival/departure time
99
+ const flightComparator = (flight1, flight2) => flight1.dateStamp - flight2.dateStamp;
100
+
101
+ const formatGate = gate => {
102
+ if (!gate) {
103
+ return { name: '-' };
104
+ }
105
+ const name = R.last(gate.name.split(' '));
106
+ return { ...gate, name };
107
+ };
108
+
109
+ const prepareFlightIn = (status, flightType, nowDate, flightDate, T) => {
110
+ if (status === constants.FlightLabelStatus.DEPARTED) {
111
+ return T('flightDetails:Departed');
112
+ } else if (status === constants.FlightLabelStatus.ARRIVED) {
113
+ return T('flightDetails:Arrived');
114
+ } else if (status === constants.FlightLabelStatus.CANCELLED) {
115
+ return null;
116
+ }
117
+
118
+ const prefix = flightType === FlightType.DEPARTURE ? 'Departs' : 'Arrives';
119
+ const minutes = minutesBetween(nowDate, flightDate);
120
+ return T(`flightDetails:${prefix} in _minutes_ minute`, { count: minutes });
121
+ };
122
+
123
+ const prepareLastUpdated = (nowDate, flightStatusUpdates, T) => {
124
+ const updateDate = R.compose(R.path(['updatedAt', 'dateUtc']), R.last)(flightStatusUpdates);
125
+ const minutes = minutesBetween(nowDate, getLocalGMTDate(updateDate));
126
+
127
+ if (minutes < 10) {
128
+ return T('flightDetails:Last updated a few minutes ago');
129
+ } else if (minutes < 60) {
130
+ return T('flightDetails:Last updated _minutes_ minutes ago', { minutes });
131
+ } else {
132
+ return T('flightDetails:Last updated over an hour ago');
133
+ }
134
+ };
135
+
136
+ /**
137
+ * Check minutes difference between two Luxon dates.
138
+ * @param {DateTime} firstDate
139
+ * @param {DateTime} secondDate
140
+ */
141
+ const minutesBetween = (firstDate, secondDate) => {
142
+ const ms = Math.abs(firstDate - secondDate);
143
+ return date.msToMin(ms);
144
+ };
145
+
146
+ const selectRawDateTime = ({ flightType, operationalTimes, departureDate, arrivalDate }) =>
147
+ flightType === FlightType.DEPARTURE
148
+ ? prepareRawDateTime(departureDate, operationalTimes.estimatedGateDeparture)
149
+ : prepareRawDateTime(arrivalDate, operationalTimes.estimatedGateArrival);
150
+
151
+ const prepareRawDateTime = (dateTime, estimatedTime) => {
152
+ const localDate = dateTime.dateLocal || dateTime.dateUtc;
153
+ const estimatedDate = estimatedTime.dateLocal || estimatedTime.dateUtc;
154
+ const isTimeChanged = estimatedDate && localDate !== estimatedDate;
155
+ return isTimeChanged ? { time: estimatedDate, oldTime: localDate } : { time: localDate };
156
+ };
157
+
158
+ /**
159
+ * Parse flight dates strings to Luxon dates relative to the venue timezone.
160
+ * @param {{ time: string, oldTime: string }} - times
161
+ * @param {string} tz - venue timezone
162
+ */
163
+ const formatToLocalDateTimes = ({ time, oldTime }, tz) => ({
164
+ localTime: getLocalGMTDate(time, tz),
165
+ localOldTime: getLocalGMTDate(oldTime, tz),
166
+ });
167
+
168
+ function mapFlightStatus(flightType, status, nowDate, localTime, localOldTime) {
169
+ if (!localTime) {
170
+ return constants.FlightLabelStatus.UNKNOWN;
171
+ }
172
+
173
+ if (nowDate > localTime) {
174
+ return lateFlightStatus(flightType);
175
+ }
176
+
177
+ status = status.toUpperCase();
178
+ if (status === 'C') {
179
+ return constants.FlightLabelStatus.CANCELLED;
180
+ }
181
+
182
+ if (!localOldTime) {
183
+ return constants.FlightLabelStatus.ON_TIME;
184
+ } else if (localTime > localOldTime) {
185
+ return constants.FlightLabelStatus.DELAYED;
186
+ } else {
187
+ return constants.FlightLabelStatus.EARLY;
188
+ }
189
+ }
190
+
191
+ const getFlightStatusText = status => {
192
+ switch (status) {
193
+ case constants.FlightLabelStatus.ON_TIME:
194
+ return 'on-time';
195
+ case constants.FlightLabelStatus.EARLY:
196
+ return 'early';
197
+ case constants.FlightLabelStatus.DELAYED:
198
+ return 'delayed';
199
+ case constants.FlightLabelStatus.CANCELLED:
200
+ return 'cancelled';
201
+ case constants.FlightLabelStatus.DEPARTED:
202
+ return 'departed';
203
+ case constants.FlightLabelStatus.ARRIVED:
204
+ return 'arrived';
205
+ default:
206
+ return 'unknown';
207
+ }
208
+ };
209
+
210
+ const lateFlightStatus = flightType =>
211
+ flightType === FlightType.DEPARTURE ? constants.FlightLabelStatus.DEPARTED : constants.FlightLabelStatus.ARRIVED;
212
+
213
+ const prepareAirportLabel = (flightType, departureAirport, arrivalAirport, T) =>
214
+ flightType === FlightType.DEPARTURE
215
+ ? T(formatAirportLabel('To'), arrivalAirport)
216
+ : T(formatAirportLabel('From'), departureAirport);
217
+
218
+ const formatAirportLabel = prefix => `flightDetails:${prefix} _city_ (_iata_)`;
219
+
220
+ const prepareBaggageClaim = (claimNum, T) =>
221
+ claimNum &&
222
+ T('flightDetails:Collect luggage from Baggage Claim _claimNum_', {
223
+ claimNum,
224
+ });
225
+
226
+ /**
227
+ * Parse date string to Luxon date relative to the venue timezone.
228
+ * @param {string} date string (can be UTC)
229
+ * @param {string} tz - venue timezone
230
+ */
231
+ const getLocalGMTDate = (date, tz) => date && luxon.DateTime.fromISO(date, { zone: tz });
232
+
233
+ const getLocalFormattedDate = (dateStr, tz, locale = 'en-US') =>
234
+ dateStr && luxon.DateTime.fromISO(dateStr, { zone: tz }).setLocale(locale).toFormat('EEE, d MMMM');
235
+
236
+ /**
237
+ * Parse date string to Luxon date in venue timezone and return short time.
238
+ * Set locale, so the returned time can match the format used in particular locale.
239
+ * E.g. for 'en-US' it will return "6:00 AM". For 'fr' it will return "6:00".
240
+ * @param {string} dateStr - date string (can be UTC)
241
+ * @param {string} tz - timezone string
242
+ * @param {string} [locale='en-US'] locale string
243
+ */
244
+ const getLocalFormattedTime = (dateStr, tz, locale = 'en-US') =>
245
+ dateStr && date.formatTime(luxon.DateTime.fromISO(dateStr, { zone: tz }), locale);
246
+
247
+ exports.FlightType = FlightType;
248
+ exports.flightComparator = flightComparator;
249
+ exports.mapFlightDetails = mapFlightDetails;
250
+ exports.mapFlightListItem = mapFlightListItem;
@@ -0,0 +1,209 @@
1
+ 'use strict';
2
+
3
+ var FlexSearch = require('flexsearch');
4
+ var luxon = require('luxon');
5
+ var R = require('ramda');
6
+ var flightDetailsMapper = require('./flightDetailsMapper.js');
7
+ var utils = require('./utils.js');
8
+
9
+ function _interopNamespaceDefault(e) {
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
27
+
28
+ function create(app, config) {
29
+ const createIndex = () =>
30
+ new FlexSearch.Index({
31
+ tokenize: 'forward',
32
+ });
33
+ const init = async () => {
34
+ state.tz = await app.bus.get('venueData/getVenueTimezone');
35
+ };
36
+
37
+ const state = {
38
+ lastUpdated: 0,
39
+ flights: { dep: null, arr: null },
40
+ index: { dep: createIndex(), arr: createIndex() },
41
+ gates: null,
42
+ apiError: false,
43
+ };
44
+
45
+ const enrichData = (flights, airportsArg, airlinesArg, flightType) => {
46
+ const airports = airportsArg.reduce((acc, obj) => {
47
+ return { ...acc, [obj.iata]: obj };
48
+ }, {});
49
+ const airlines = airlinesArg
50
+ .flatMap(airline => [
51
+ { code: airline.iata, airline },
52
+ { code: airline.icao, airline },
53
+ ])
54
+ .filter(({ code }) => code)
55
+ .reduce((acc, { code, airline }) => {
56
+ return { ...acc, [code]: airline };
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);
63
+ const gatePoi = state.gates[gateId];
64
+ return {
65
+ ...flight,
66
+ flightType,
67
+ gatePoi,
68
+ airline: airlines[flight.carrierFsCode],
69
+ departureAirport: airports[flight.departureAirportFsCode],
70
+ arrivalAirport: airports[flight.arrivalAirportFsCode],
71
+ };
72
+ });
73
+ };
74
+
75
+ const updateIndexes = (type, flightStatuses) => {
76
+ state.index[type] = createIndex();
77
+ state.flights[type] = {};
78
+ flightStatuses.forEach(status => {
79
+ state.index[type].add(status.flightId, createFlightSearchEntry(status));
80
+ state.flights[type][status.flightId] = status;
81
+ });
82
+ };
83
+
84
+ const searchPropertiesPaths = [
85
+ ['flightNumber'],
86
+ ['airline', 'iata'],
87
+ ['airline', 'name'],
88
+ ['arrivalAirport', 'iata'],
89
+ ['arrivalAirport', 'city'],
90
+ ['departureAirport', 'iata'],
91
+ ['departureAirport', 'city'],
92
+ ];
93
+ const createFlightSearchEntry = R__namespace.pipe(
94
+ // apply each function one after another to passed object
95
+ R__namespace.juxt(R__namespace.map(R__namespace.path, searchPropertiesPaths)), // safe collect of nested properties into list
96
+ R__namespace.filter(R__namespace.identity), // filter 'falsy' values
97
+ R__namespace.join(' '),
98
+ );
99
+
100
+ const indexGatePois = async () => {
101
+ if (state.gates === null) {
102
+ const gatePois = await app.bus.get('poi/getByCategoryId', {
103
+ categoryId: 'gate',
104
+ });
105
+ const parseGate = ({ name }) => R__namespace.tail(name.replace(',', '').split(' '));
106
+ const pairs = R__namespace.reduce(
107
+ (acc, poi) => {
108
+ const gateIds = parseGate(poi);
109
+ const gateAndPoiPairs = R__namespace.map(gateId => [gateId, poi], gateIds);
110
+ return [...acc, ...gateAndPoiPairs];
111
+ },
112
+ [],
113
+ Object.values(gatePois),
114
+ );
115
+
116
+ state.gates = R__namespace.fromPairs(pairs);
117
+ }
118
+ return state;
119
+ };
120
+
121
+ const updateFlights = async () => {
122
+ await indexGatePois();
123
+ const venueData = await app.bus.get('venueData/getVenueData');
124
+ const params = new URLSearchParams();
125
+ const locale = app.i18n?.().language;
126
+ if (locale) {
127
+ params.append('locale', locale);
128
+ }
129
+ if (config?.timeRange) {
130
+ const now = Date.now();
131
+ const startDate = new Date(now - config.timeRange.beforeNowMs).toISOString();
132
+ const endDate = new Date(now + config.timeRange.afterNowMs).toISOString();
133
+ params.append('startDate', startDate);
134
+ params.append('endDate', endDate);
135
+ }
136
+
137
+ const baseURL = `https://marketplace.locuslabs.com/venueId/${venueData.baseVenueId}/flight-status`;
138
+ const apiURL = params.toString() ? `${baseURL}?${params.toString()}` : baseURL;
139
+
140
+ try {
141
+ const response = await fetch(apiURL);
142
+ const data = await response.json();
143
+ [flightDetailsMapper.FlightType.ARRIVAL, flightDetailsMapper.FlightType.DEPARTURE].forEach(type => {
144
+ const key = type === flightDetailsMapper.FlightType.DEPARTURE ? 'departures' : 'arrivals';
145
+ const { airports, airlines } = data.data[key].appendix;
146
+ updateIndexes(type, enrichData(data.data[key].flightStatuses, airports, airlines, type));
147
+ });
148
+ state.apiError = false;
149
+ } catch (error) {
150
+ state.apiError = true;
151
+ console.error('Error from flight status api call', 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
154
+ updateIndexes(type, []);
155
+ });
156
+ } finally {
157
+ state.lastUpdated = Date.now();
158
+ }
159
+ return state;
160
+ };
161
+
162
+ const checkFlights = async () => {
163
+ // if the data was not update in the last minute, update it
164
+ if (Date.now() - state.lastUpdated > 60 * 1000) {
165
+ await updateFlights();
166
+ }
167
+ };
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 } = {}) => {
176
+ await checkFlights();
177
+ return utils.searchFlights(term, type, state);
178
+ });
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 }) => {
185
+ await checkFlights();
186
+ const flight = state.flights.dep[flightId] || state.flights.arr[flightId];
187
+ return flight;
188
+ });
189
+
190
+ app.bus.on('flightStatus/mapFlightDetails', async ({ flight }) => {
191
+ return flightDetailsMapper.mapFlightDetails(luxon.DateTime.local(), flight, app.gt(), state.tz, app.i18n().language);
192
+ });
193
+
194
+ app.bus.on('flightStatus/mapFlightListItems', async ({ flights }) => {
195
+ return flights
196
+ .map(flight => flightDetailsMapper.mapFlightListItem(luxon.DateTime.local(), flight, app.gt(), state.tz, app.i18n().language))
197
+ .sort(flightDetailsMapper.flightComparator);
198
+ });
199
+
200
+ return {
201
+ init,
202
+ internal: {
203
+ updateFlights,
204
+ indexGatePois,
205
+ },
206
+ };
207
+ }
208
+
209
+ exports.create = create;
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var flightDetailsMapper = require('./flightDetailsMapper.js');
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
+ const searchFlights = (term, type, state) => {
13
+ const { index, flights, apiError } = state;
14
+ const types = type === flightDetailsMapper.FlightType.ALL ? [flightDetailsMapper.FlightType.DEPARTURE, flightDetailsMapper.FlightType.ARRIVAL] : [type];
15
+
16
+ let flightResults;
17
+ if (term) {
18
+ flightResults = types.flatMap(t => {
19
+ const ids = index[t].search({ query: term });
20
+ return ids.map(id => flights[t][id]);
21
+ });
22
+ } else {
23
+ flightResults = types.flatMap(t => Object.values(flights[t]));
24
+ }
25
+
26
+ if (flightResults.length === 0 && /^\w\w\d{2,4}$/.test(term)) {
27
+ // When user seach for flight UA4567, we will need to convert it to UA_4567 for a valid search result.
28
+ const modifiedTerm = term.replace(/(\w\w)(\d{2,4})/, '$1_$2');
29
+ return searchFlights(modifiedTerm, type, state);
30
+ }
31
+ return { flights: flightResults, apiError };
32
+ };
33
+
34
+ exports.searchFlights = searchFlights;
@@ -69,6 +69,13 @@ const headlessCommands = [
69
69
  { name: 'details', type: 'boolean', optional: true },
70
70
  ],
71
71
  },
72
+ {
73
+ command: 'getFlightStatus',
74
+ args: [
75
+ { name: 'term', type: 'string', optional: true },
76
+ { name: 'type', type: 'string', optional: true },
77
+ ],
78
+ },
72
79
  ];
73
80
 
74
81
  function handleHeadless(app) {
@@ -139,6 +146,10 @@ function handleHeadless(app) {
139
146
  return details ? poiList : poiIdList;
140
147
  }),
141
148
  );
149
+
150
+ app.bus.on('clientAPI/getFlightStatus', async ({ term, type = 'all' }) =>
151
+ app.bus.get('flightStatus/query', { term, type }),
152
+ );
142
153
  }
143
154
 
144
155
  exports.handleHeadless = handleHeadless;
@@ -17,6 +17,8 @@ var plugins = {
17
17
  },
18
18
  dynamicPois: {
19
19
  },
20
+ flightStatus: {
21
+ },
20
22
  poiDataManager: {
21
23
  },
22
24
  sdkServer: {
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var luxon = require('luxon');
4
+
5
+ /**
6
+ * Pass in a luxon DateTime object and receive a simple formatted time string
7
+ * This adjusts for odd handling of Icelandic times by Chromium/Blink browser engines.
8
+ * @param {DateTime|Date} datetime A JS Date or a luxon DateTime holding the time you wish to display
9
+ * @param {string} locale The locale (2 character country code - plus optional variant)
10
+ * @returns {string} A time formatted for display
11
+ */
12
+ const formatTime = (datetime, locale = 'en') => {
13
+ if (datetime instanceof Date) {
14
+ datetime = luxon.DateTime(datetime);
15
+ }
16
+
17
+ // The following is to force Icelandic (is) locale to display in 24 hour format (the "ca" locale
18
+ // is an arbitrarily selected locale that uses 24 hour format)
19
+ // This is due to Chrome/Chromium/Blink not supporting Icelandic well. See https://issues.chromium.org/issues/40624456
20
+ if (locale === 'is') {
21
+ locale = 'ca';
22
+ }
23
+
24
+ return datetime.setLocale(locale).toLocaleString(luxon.DateTime.TIME_SIMPLE);
25
+ };
26
+ const msToMin = ms => Math.ceil(ms / 60 / 1000);
27
+
28
+ exports.formatTime = formatTime;
29
+ exports.msToMin = msToMin;
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const FlightLabelStatus = {
4
+ ON_TIME: 1,
5
+ EARLY: 2,
6
+ DELAYED: 3,
7
+ CANCELLED: 4,
8
+ ARRIVED: 5,
9
+ DEPARTED: 6,
10
+ UNKNOWN: 7,
11
+ };
12
+
13
+ exports.FlightLabelStatus = FlightLabelStatus;
@@ -1 +1 @@
1
- var e="web-engine",t="3.3.834",s="UNLICENSED",r="module",o="src/main.js",i=["demo","deploy","nodesdk","src/extModules/flexapi","services/*","libraries/*"],a={"build-storybook":"storybook build",colors:"cat utils/colors1.txt && node utils/processColors.js | pbcopy && cat utils/colors2.txt","cypress:comp":"cypress open --component --browser chrome","cypress:comp:ci":"cypress run --component",demo:"cd demo/ && yarn start",dev:"yarn mol e2e","format:check":"yarn prettier . --check","format:fix":"yarn prettier . --write",goProd:"cd deploy && scripts/goProd.sh",goStaging:"deploy/scripts/goStaging.sh","icons:convert":"node scripts/convertSvgToJsx.mjs",lint:"eslint . --ext .js,.jsx,.ts,.tsx",mod:"demo/startMod.sh",mol:"demo/startMol.sh","mol:build":"demo/startMolBuild.sh",molProd:"cd deploy && yarn buildAndRunMol","playwright:ci":"yarn playwright test --grep-invert sdk","playwright:ci:failed":"yarn playwright test --last-failed --grep-invert sdk","playwright:sdk":"yarn start-server-and-test 'cd ./deploy && yarn buildDev && yarn serveLocal' 8085 'cd ./test/sdk && npx http-server' 8080 'yarn playwright test sdk --ui'","playwright:ui":"yarn playwright test --ui --grep-invert sdk",prepare:"husky",storybook:"storybook dev -p 6006",test:"vitest run","test-watch":"vitest --watch","test:all":"yarn lint && yarn format:check && yarn test && yarn cypress:comp:ci && yarn playwright:ci","test:mod":"playwright test --config=playwright.mod.config.ts",typecheck:"tsc -p tsconfig.checkjs.json"},l=["defaults"],n={"@azure/event-hubs":"^5.12.2","@csstools/normalize.css":"^11.0.1","@dnd-kit/core":"^6.3.1","@dnd-kit/modifiers":"^9.0.0","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@locus-labs/mod-badge":"^0.1.102","@locus-labs/mod-footer":"^0.0.111","@locus-labs/mod-header":"^0.0.105","@locus-labs/mod-location-marker":"^0.0.104","@locus-labs/mod-map-legend":"^0.0.104","@locus-labs/mod-offscreen-indicator":"^0.0.104","@locus-labs/mod-pin":"^0.0.104","@locus-labs/mod-qr-code-card":"^0.0.104","@locus-labs/mod-qr-code-window":"^0.0.105","@locus-labs/mod-walk-time-matrix":"^0.0.103","@mapbox/mapbox-gl-draw":"^1.5.0","@mapbox/mapbox-gl-draw-static-mode":"^1.0.1","@microsoft/applicationinsights-web":"^3.3.6","@turf/area":"^7.2.0","@turf/bbox-clip":"^7.2.0","@turf/bbox-polygon":"^7.2.0","@turf/bearing":"^7.2.0","@turf/circle":"^7.2.0","@turf/helpers":"^7.2.0","@turf/point-to-line-distance":"^7.2.0","@vitejs/plugin-react":"^5.2.0","@zumer/snapdom":"^2.9.0","axe-core":"^4.10.3",browserslist:"^4.27.0","crypto-browserify":"^3.12.1","cypress-multi-reporters":"^2.0.5","cypress-real-events":"^1.14.0",dompurify:"^3.3.3","file-loader":"^6.2.0",flexsearch:"^0.7.43","h3-js":"^4.1.0",i18next:"^26.0.0","i18next-browser-languagedetector":"^6.1.1",jsdom:"^25.0.1",jsonschema:"^1.5.0",luxon:"^3.5.0","maplibre-gl":"^4.7.1","mini-css-extract-plugin":"^2.9.2","mocha-junit-reporter":"^2.2.1",mochawesome:"^7.1.3","node-polyfill-webpack-plugin":"^4.1.0","path-browserify":"^1.0.1",pmtiles:"^4.4.0","prop-types":"^15.8.1","qrcode.react":"^4.2.0",ramda:"^0.30.1",react:"^19.2.4","react-compound-slider":"^3.4.0","react-dom":"^19.2.4","react-json-editor-ajrm":"^2.5.14","react-svg":"^16.3.0","react-virtualized-auto-sizer":"^1.0.25","react-window":"^1.8.11","smoothscroll-polyfill":"^0.4.4","styled-components":"^6.1.15","styled-normalize":"^8.1.1","throttle-debounce":"^5.0.2",trackjs:"^3.10.4","ua-parser-js":"^0.7.40",uuid:"11.1.0",zousan:"^3.0.1","zousan-plus":"^4.0.1"},c={"@applitools/eyes-playwright":"^1.46.8","@axe-core/playwright":"^4.10.2","@azure/identity":"^4.13.0","@azure/playwright":"^1.0.0","@playwright/test":"^1.59.1","@storybook/addon-essentials":"^8.6.15","@storybook/blocks":"^8.6.15","@storybook/react":"^8.6.15","@storybook/react-vite":"^8.6.15","@testing-library/jest-dom":"^6.6.3","@types/react":"^19.0.10","@types/react-dom":"^19.0.4","@typescript-eslint/eslint-plugin":"^8.26.1","@typescript-eslint/parser":"^8.26.1","chai-colors":"^1.0.1","css-loader":"^7.1.2",cypress:"^15.0.0","cypress-wait-until":"^3.0.2",eslint:"^8.57.1","eslint-config-prettier":"^10.1.8","eslint-config-standard":"^17.1.0","eslint-import-resolver-alias":"^1.1.2","eslint-import-resolver-typescript":"^3.9.1","eslint-plugin-cypress":"^2.15.2","eslint-plugin-import":"^2.31.0","eslint-plugin-n":"^17.16.2","eslint-plugin-node":"^11.1.0","eslint-plugin-playwright":"^2.2.2","eslint-plugin-promise":"^5.2.0","eslint-plugin-react":"^7.37.4","eslint-plugin-standard":"^5.0.0","eslint-plugin-vitest":"^0.5.4","fetch-mock":"^12.6.0",glob:"^11.0.1",husky:"^9.1.7","lint-staged":"^16.4.0","node-fetch":"^2.7.0","null-loader":"^4.0.1",nx:"19.8.14","nx-remotecache-azure":"^19.0.0","os-browserify":"^0.3.0",prettier:"^3.8.3","start-server-and-test":"^2.0.11",storybook:"^8.6.15",typescript:"^5.8.2",vite:"^7.3.2",vitest:"^4.1.2","webpack-merge":"^6.0.1"},p="yarn@4.13.0",d={node:"24.x"},y={},m={name:e,version:t,private:!0,license:s,type:r,main:o,workspaces:i,scripts:a,"lint-staged":{"*.js":["eslint --fix","prettier --check"],"*.{json,md,css,ts,tsx,jsx}":["prettier --check"],"src/i18n/**/*.json":["node utils/sort-json.js","prettier --write"]},browserslist:l,dependencies:n,devDependencies:c,packageManager:p,engines:d,nx:y};export{l as browserslist,m as default,n as dependencies,c as devDependencies,d as engines,s as license,o as main,e as name,y as nx,p as packageManager,a as scripts,r as type,t as version,i as workspaces};
1
+ var e="web-engine",t="3.3.836",s="UNLICENSED",r="module",o="src/main.js",i=["demo","deploy","nodesdk","src/extModules/flexapi","services/*","libraries/*"],a={"build-storybook":"storybook build",colors:"cat utils/colors1.txt && node utils/processColors.js | pbcopy && cat utils/colors2.txt","cypress:comp":"cypress open --component --browser chrome","cypress:comp:ci":"cypress run --component",demo:"cd demo/ && yarn start",dev:"yarn mol e2e","format:check":"yarn prettier . --check","format:fix":"yarn prettier . --write",goProd:"cd deploy && scripts/goProd.sh",goStaging:"deploy/scripts/goStaging.sh","icons:convert":"node scripts/convertSvgToJsx.mjs",lint:"eslint . --ext .js,.jsx,.ts,.tsx",mod:"demo/startMod.sh",mol:"demo/startMol.sh","mol:build":"demo/startMolBuild.sh",molProd:"cd deploy && yarn buildAndRunMol","playwright:ci":"yarn playwright test --grep-invert sdk","playwright:ci:failed":"yarn playwright test --last-failed --grep-invert sdk","playwright:sdk":"yarn start-server-and-test 'cd ./deploy && yarn buildDev && yarn serveLocal' 8085 'cd ./test/sdk && npx http-server' 8080 'yarn playwright test sdk --ui'","playwright:ui":"yarn playwright test --ui --grep-invert sdk",prepare:"husky",storybook:"storybook dev -p 6006",test:"vitest run","test-watch":"vitest --watch","test:all":"yarn lint && yarn format:check && yarn test && yarn cypress:comp:ci && yarn playwright:ci","test:mod":"playwright test --config=playwright.mod.config.ts",typecheck:"tsc -p tsconfig.checkjs.json"},l=["defaults"],n={"@azure/event-hubs":"^5.12.2","@csstools/normalize.css":"^11.0.1","@dnd-kit/core":"^6.3.1","@dnd-kit/modifiers":"^9.0.0","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@locus-labs/mod-badge":"^0.1.102","@locus-labs/mod-footer":"^0.0.111","@locus-labs/mod-header":"^0.0.105","@locus-labs/mod-location-marker":"^0.0.104","@locus-labs/mod-map-legend":"^0.0.104","@locus-labs/mod-offscreen-indicator":"^0.0.104","@locus-labs/mod-pin":"^0.0.104","@locus-labs/mod-qr-code-card":"^0.0.104","@locus-labs/mod-qr-code-window":"^0.0.105","@locus-labs/mod-walk-time-matrix":"^0.0.103","@mapbox/mapbox-gl-draw":"^1.5.0","@mapbox/mapbox-gl-draw-static-mode":"^1.0.1","@microsoft/applicationinsights-web":"^3.3.6","@turf/area":"^7.2.0","@turf/bbox-clip":"^7.2.0","@turf/bbox-polygon":"^7.2.0","@turf/bearing":"^7.2.0","@turf/circle":"^7.2.0","@turf/helpers":"^7.2.0","@turf/point-to-line-distance":"^7.2.0","@vitejs/plugin-react":"^5.2.0","@zumer/snapdom":"^2.9.0","axe-core":"^4.10.3",browserslist:"^4.27.0","crypto-browserify":"^3.12.1","cypress-multi-reporters":"^2.0.5","cypress-real-events":"^1.14.0",dompurify:"^3.3.3","file-loader":"^6.2.0",flexsearch:"^0.7.43","h3-js":"^4.1.0",i18next:"^26.0.0","i18next-browser-languagedetector":"^6.1.1",jsdom:"^25.0.1",jsonschema:"^1.5.0",luxon:"^3.5.0","maplibre-gl":"^4.7.1","mini-css-extract-plugin":"^2.9.2","mocha-junit-reporter":"^2.2.1",mochawesome:"^7.1.3","node-polyfill-webpack-plugin":"^4.1.0","path-browserify":"^1.0.1",pmtiles:"^4.4.0","prop-types":"^15.8.1","qrcode.react":"^4.2.0",ramda:"^0.30.1",react:"^19.2.4","react-compound-slider":"^3.4.0","react-dom":"^19.2.4","react-json-editor-ajrm":"^2.5.14","react-svg":"^16.3.0","react-virtualized-auto-sizer":"^1.0.25","react-window":"^1.8.11","smoothscroll-polyfill":"^0.4.4","styled-components":"^6.1.15","styled-normalize":"^8.1.1","throttle-debounce":"^5.0.2",trackjs:"^3.10.4","ua-parser-js":"^0.7.40",uuid:"11.1.0",zousan:"^3.0.1","zousan-plus":"^4.0.1"},c={"@applitools/eyes-playwright":"^1.46.8","@axe-core/playwright":"^4.10.2","@azure/identity":"^4.13.0","@azure/playwright":"^1.0.0","@playwright/test":"^1.59.1","@storybook/addon-essentials":"^8.6.15","@storybook/blocks":"^8.6.15","@storybook/react":"^8.6.15","@storybook/react-vite":"^8.6.15","@testing-library/jest-dom":"^6.6.3","@types/react":"^19.0.10","@types/react-dom":"^19.0.4","@typescript-eslint/eslint-plugin":"^8.26.1","@typescript-eslint/parser":"^8.26.1","chai-colors":"^1.0.1","css-loader":"^7.1.2",cypress:"^15.0.0","cypress-wait-until":"^3.0.2",eslint:"^8.57.1","eslint-config-prettier":"^10.1.8","eslint-config-standard":"^17.1.0","eslint-import-resolver-alias":"^1.1.2","eslint-import-resolver-typescript":"^3.9.1","eslint-plugin-cypress":"^2.15.2","eslint-plugin-import":"^2.31.0","eslint-plugin-n":"^17.16.2","eslint-plugin-node":"^11.1.0","eslint-plugin-playwright":"^2.2.2","eslint-plugin-promise":"^5.2.0","eslint-plugin-react":"^7.37.4","eslint-plugin-standard":"^5.0.0","eslint-plugin-vitest":"^0.5.4","fetch-mock":"^12.6.0",glob:"^11.0.1",husky:"^9.1.7","lint-staged":"^16.4.0","node-fetch":"^2.7.0","null-loader":"^4.0.1",nx:"19.8.14","nx-remotecache-azure":"^19.0.0","os-browserify":"^0.3.0",prettier:"^3.8.3","start-server-and-test":"^2.0.11",storybook:"^8.6.15",typescript:"^5.8.2",vite:"^7.3.2",vitest:"^4.1.2","webpack-merge":"^6.0.1"},p="yarn@4.13.0",d={node:"24.x"},y={},m={name:e,version:t,private:!0,license:s,type:r,main:o,workspaces:i,scripts:a,"lint-staged":{"*.js":["eslint --fix","prettier --check"],"*.{json,md,css,ts,tsx,jsx}":["prettier --check"],"src/i18n/**/*.json":["node utils/sort-json.js","prettier --write"]},browserslist:l,dependencies:n,devDependencies:c,packageManager:p,engines:d,nx:y};export{l as browserslist,m as default,n as dependencies,c as devDependencies,d as engines,s as license,o as main,e as name,y as nx,p as packageManager,a as scripts,r as type,t as version,i as workspaces};
@@ -0,0 +1 @@
1
+ import{DateTime as t}from"luxon";import{pick as e,propOr as a,last as r,compose as i,path as l}from"ramda";import{formatTime as s,msToMin as o}from"../../../src/utils/date.js";import{FlightLabelStatus as n}from"../../../utils/constants.js";const m={ARRIVAL:"arr",DEPARTURE:"dep",ALL:"all"};function u(t,e,r,i,l){const{flightId:s,carrierFsCode:o,flightNumber:n,airline:u,flightType:d,departureAirport:g,arrivalAirport:D,airportResources:f,gatePoi:p,status:E}=e,L=A(e),{localTime:C,localOldTime:U}=R(L,i),P=h(d,E,t,C,U),$=d===m.DEPARTURE?"flightDetails:Departs _date_":"flightDetails:Arrives _date_";return{flightId:s,name:`${a("","name",u)} - ${o} ${n}`,status:P,statusText:r(`flightDetails:${T(P)}`),baggageClaim:d===m.ARRIVAL?I(f.arrivalBagClaim,r):void 0,connectionAirport:v(d,g,D,r),time:N(C,i,l),oldTime:N(U,i,l),date:r($,{date:_(C,i,l)}),dateStamp:C.toMillis(),gate:c(p),gateLabel:r("flightDetails:Gate")}}function d(t,r,i,l,s){const{flightNumber:o,flightType:n,departureAirport:u,arrivalAirport:d,airportResources:g,flightStatusUpdates:p,carrierFsCode:E,gatePoi:L,airline:C,status:U}=r,P=e(["city","iata"]),$=A(r),{localTime:y,localOldTime:O}=R($,l),S=h(n,U,t,y,O);return{flightType:n,flightTypeLabel:i(`flightDetails:${n===m.DEPARTURE?"Departure":"Arrival"}`),name:`${a("","name",C)} - ${E} ${o}`,status:S,statusText:i(`flightDetails:${T(S)}`),baggageClaim:n===m.ARRIVAL?I(g.arrivalBagClaim,i):void 0,departure:P(u),arrival:P(d),connectionAirport:v(n,u,d,i),flightIn:D(S,n,t,y,i),time:N(y,l,s),oldTime:N(O,l,s),date:_(y,l,s),lastUpdated:f(t,p,i),flightDuration:"",gateLabel:i("flightDetails:Gate"),gate:c(L),tags:[],flightIconBaseName:n===m.ARRIVAL?"arrivals":"departures"}}const g=(t,e)=>t.dateStamp-e.dateStamp,c=t=>{if(!t)return{name:"-"};const e=r(t.name.split(" "));return{...t,name:e}},D=(t,e,a,r,i)=>{if(t===n.DEPARTED)return i("flightDetails:Departed");if(t===n.ARRIVED)return i("flightDetails:Arrived");if(t===n.CANCELLED)return null;return i(`flightDetails:${e===m.DEPARTURE?"Departs":"Arrives"} in _minutes_ minute`,{count:p(a,r)})},f=(t,e,a)=>{const s=i(l(["updatedAt","dateUtc"]),r)(e),o=p(t,U(s));return o<10?a("flightDetails:Last updated a few minutes ago"):o<60?a("flightDetails:Last updated _minutes_ minutes ago",{minutes:o}):a("flightDetails:Last updated over an hour ago")},p=(t,e)=>{const a=Math.abs(t-e);return o(a)},A=({flightType:t,operationalTimes:e,departureDate:a,arrivalDate:r})=>t===m.DEPARTURE?E(a,e.estimatedGateDeparture):E(r,e.estimatedGateArrival),E=(t,e)=>{const a=t.dateLocal||t.dateUtc,r=e.dateLocal||e.dateUtc;return r&&a!==r?{time:r,oldTime:a}:{time:a}},R=({time:t,oldTime:e},a)=>({localTime:U(t,a),localOldTime:U(e,a)});function h(t,e,a,r,i){return r?a>r?L(t):"C"===(e=e.toUpperCase())?n.CANCELLED:i?r>i?n.DELAYED:n.EARLY:n.ON_TIME:n.UNKNOWN}const T=t=>{switch(t){case n.ON_TIME:return"on-time";case n.EARLY:return"early";case n.DELAYED:return"delayed";case n.CANCELLED:return"cancelled";case n.DEPARTED:return"departed";case n.ARRIVED:return"arrived";default:return"unknown"}},L=t=>t===m.DEPARTURE?n.DEPARTED:n.ARRIVED,v=(t,e,a,r)=>t===m.DEPARTURE?r(C("To"),a):r(C("From"),e),C=t=>`flightDetails:${t} _city_ (_iata_)`,I=(t,e)=>t&&e("flightDetails:Collect luggage from Baggage Claim _claimNum_",{claimNum:t}),U=(e,a)=>e&&t.fromISO(e,{zone:a}),_=(e,a,r="en-US")=>e&&t.fromISO(e,{zone:a}).setLocale(r).toFormat("EEE, d MMMM"),N=(e,a,r="en-US")=>e&&s(t.fromISO(e,{zone:a}),r);export{m as FlightType,g as flightComparator,d as mapFlightDetails,u as mapFlightListItem};
@@ -0,0 +1 @@
1
+ import t from"flexsearch";import{DateTime as a}from"luxon";import*as e from"ramda";import{FlightType as r,mapFlightDetails as i,mapFlightListItem as n,flightComparator as o}from"./flightDetailsMapper.js";import{searchFlights as s}from"./utils.js";function l(l,p){const u=()=>new t.Index({tokenize:"forward"}),g={lastUpdated:0,flights:{dep:null,arr:null},index:{dep:u(),arr:u()},gates:null,apiError:!1},c=(t,a)=>{g.index[t]=u(),g.flights[t]={},a.forEach(a=>{g.index[t].add(a.flightId,d(a)),g.flights[t][a.flightId]=a})},d=e.pipe(e.juxt(e.map(e.path,[["flightNumber"],["airline","iata"],["airline","name"],["arrivalAirport","iata"],["arrivalAirport","city"],["departureAirport","iata"],["departureAirport","city"]])),e.filter(e.identity),e.join(" ")),f=async()=>{if(null===g.gates){const t=await l.bus.get("poi/getByCategoryId",{categoryId:"gate"}),a=({name:t})=>e.tail(t.replace(",","").split(" ")),r=e.reduce((t,r)=>{const i=a(r);return[...t,...e.map(t=>[t,r],i)]},[],Object.values(t));g.gates=e.fromPairs(r)}return g},h=async()=>{await f();const t=await l.bus.get("venueData/getVenueData"),a=new URLSearchParams,i=l.i18n?.().language;if(i&&a.append("locale",i),p?.timeRange){const t=Date.now(),e=new Date(t-p.timeRange.beforeNowMs).toISOString(),r=new Date(t+p.timeRange.afterNowMs).toISOString();a.append("startDate",e),a.append("endDate",r)}const n=`https://marketplace.locuslabs.com/venueId/${t.baseVenueId}/flight-status`,o=a.toString()?`${n}?${a.toString()}`:n;try{const t=await fetch(o),a=await t.json();[r.ARRIVAL,r.DEPARTURE].forEach(t=>{const i=t===r.DEPARTURE?"departures":"arrivals",{airports:n,airlines:o}=a.data[i].appendix;c(t,((t,a,i,n)=>{const o=a.reduce((t,a)=>({...t,[a.iata]:a}),{}),s=i.flatMap(t=>[{code:t.iata,airline:t},{code:t.icao,airline:t}]).filter(({code:t})=>t).reduce((t,{code:a,airline:e})=>({...t,[a]:e}),{});return t.map(t=>{const a=n===r.DEPARTURE?e.pathOr("",["airportResources","departureGate"],t):e.pathOr("",["airportResources","arrivalGate"],t),i=g.gates[a];return{...t,flightType:n,gatePoi:i,airline:s[t.carrierFsCode],departureAirport:o[t.departureAirportFsCode],arrivalAirport:o[t.arrivalAirportFsCode]}})})(a.data[i].flightStatuses,n,o,t))}),g.apiError=!1}catch(t){g.apiError=!0,console.error("Error from flight status api call",t),[r.ARRIVAL,r.DEPARTURE].forEach(t=>{c(t,[])})}finally{g.lastUpdated=Date.now()}return g},m=async()=>{Date.now()-g.lastUpdated>6e4&&await h()};return l.bus.on("flightStatus/query",async({term:t=null,type:a=r.DEPARTURE}={})=>(await m(),s(t,a,g))),l.bus.on("flightStatus/getFlight",async({flightId:t})=>{await m();return g.flights.dep[t]||g.flights.arr[t]}),l.bus.on("flightStatus/mapFlightDetails",async({flight:t})=>i(a.local(),t,l.gt(),g.tz,l.i18n().language)),l.bus.on("flightStatus/mapFlightListItems",async({flights:t})=>t.map(t=>n(a.local(),t,l.gt(),g.tz,l.i18n().language)).sort(o)),{init:async()=>{g.tz=await l.bus.get("venueData/getVenueTimezone")},internal:{updateFlights:h,indexGatePois:f}}}export{l as create};
@@ -0,0 +1 @@
1
+ import{FlightType as t}from"./flightDetailsMapper.js";const r=(e,a,l)=>{const{index:p,flights:s,apiError:i}=l,o=a===t.ALL?[t.DEPARTURE,t.ARRIVAL]:[a];let f;if(f=e?o.flatMap(t=>p[t].search({query:e}).map(r=>s[t][r])):o.flatMap(t=>Object.values(s[t])),0===f.length&&/^\w\w\d{2,4}$/.test(e)){const t=e.replace(/(\w\w)(\d{2,4})/,"$1_$2");return r(t,a,l)}return{flights:f,apiError:i}};export{r as searchFlights};
@@ -1 +1 @@
1
- import*as e from"ramda";import{locationToEndpoint as t,getStructures as n}from"../../../src/utils/location.js";const i=[{command:"destroy"},{command:"getDirections",args:[{name:"from",type:"location"},{name:"to",type:"location"},{name:"accessible",type:"boolean",optional:!0},{name:"queueTypes",type:"list",itemType:{type:"string"},optional:!0}]},{command:"getDirectionsMultiple",args:[{name:"locations",type:"list",itemType:{type:"location"}},{name:"accessible",type:"boolean",optional:!0},{name:"queueTypes",type:"list",itemType:{type:"string"},optional:!0}]},{command:"getPOIDetails",args:[{name:"poiId",type:"integer",min:0}]},{command:"getAllPOIs"},{command:"getStructures"},{command:"getVenueData"},{command:"getSecurityWaitTimes",args:[{name:"isOpen",type:"boolean",optional:!0}]},{command:"search",args:[{name:"term",type:"string",minLength:2},{name:"details",type:"boolean",optional:!0}]}];function s(i){i.bus.on("clientAPI/destroy",async()=>i.destroy()),i.bus.on("clientAPI/getDirections",async({from:n,to:s,accessible:a,queueTypes:o})=>{const c=await t(i,n),r=await t(i,s),m={requiresAccessibility:!!a};return o&&(m.selectedSecurityLanes={SecurityLane:o}),i.bus.get("wayfinder/getRoute",{fromEndpoint:c,toEndpoint:r,options:m}).then(e.pick(["distance","time","steps","navline","waypoints"]))}),i.bus.on("clientAPI/getDirectionsMultiple",async({locations:n,accessible:s,queueTypes:a})=>{const o=await Promise.all(n.map(async e=>t(i,e))),c={requiresAccessibility:!!s};a&&(c.selectedSecurityLanes={SecurityLane:a});const r=await Promise.all(e.aperture(2,o).map(async e=>i.bus.get("wayfinder/getRoute",{fromEndpoint:e[0],toEndpoint:e[1],options:c}))),m=e.map(e.pick(["distance","time","steps","navline","waypoints"]),r);return{total:{distance:e.sum(e.map(e=>e.distance,m)),time:e.sum(e.map(e=>e.time,m))},directions:m}}),i.bus.on("clientAPI/getPOIDetails",async({poiId:e})=>i.bus.get("poi/getById",{id:e})),i.bus.on("clientAPI/getAllPOIs",async()=>i.bus.get("poi/getAll")),i.bus.on("clientAPI/getStructures",()=>n(i)),i.bus.on("clientAPI/getSecurityWaitTimes",async({isOpen:e})=>i.bus.get("dynamicPois/getSecurityWaitTimes",{isOpen:e}));const s=e=>"function"!=typeof e;i.bus.on("clientAPI/getVenueData",async()=>{const t=await i.bus.get("venueData/getVenueData");return e.filter(s,t)}),i.bus.on("clientAPI/search",async({term:e,details:t})=>i.bus.get("search/queryAsync",{term:e}).then(n=>{const s=n.map(e=>e.poiId);return i.bus.send("event/search",{referrer:"prog",searchMethod:null,query:e,entities:s}),t?n:s}))}export{s as handleHeadless,i as headlessCommands};
1
+ import*as e from"ramda";import{locationToEndpoint as t,getStructures as n}from"../../../src/utils/location.js";const i=[{command:"destroy"},{command:"getDirections",args:[{name:"from",type:"location"},{name:"to",type:"location"},{name:"accessible",type:"boolean",optional:!0},{name:"queueTypes",type:"list",itemType:{type:"string"},optional:!0}]},{command:"getDirectionsMultiple",args:[{name:"locations",type:"list",itemType:{type:"location"}},{name:"accessible",type:"boolean",optional:!0},{name:"queueTypes",type:"list",itemType:{type:"string"},optional:!0}]},{command:"getPOIDetails",args:[{name:"poiId",type:"integer",min:0}]},{command:"getAllPOIs"},{command:"getStructures"},{command:"getVenueData"},{command:"getSecurityWaitTimes",args:[{name:"isOpen",type:"boolean",optional:!0}]},{command:"search",args:[{name:"term",type:"string",minLength:2},{name:"details",type:"boolean",optional:!0}]},{command:"getFlightStatus",args:[{name:"term",type:"string",optional:!0},{name:"type",type:"string",optional:!0}]}];function s(i){i.bus.on("clientAPI/destroy",async()=>i.destroy()),i.bus.on("clientAPI/getDirections",async({from:n,to:s,accessible:a,queueTypes:o})=>{const c=await t(i,n),r=await t(i,s),m={requiresAccessibility:!!a};return o&&(m.selectedSecurityLanes={SecurityLane:o}),i.bus.get("wayfinder/getRoute",{fromEndpoint:c,toEndpoint:r,options:m}).then(e.pick(["distance","time","steps","navline","waypoints"]))}),i.bus.on("clientAPI/getDirectionsMultiple",async({locations:n,accessible:s,queueTypes:a})=>{const o=await Promise.all(n.map(async e=>t(i,e))),c={requiresAccessibility:!!s};a&&(c.selectedSecurityLanes={SecurityLane:a});const r=await Promise.all(e.aperture(2,o).map(async e=>i.bus.get("wayfinder/getRoute",{fromEndpoint:e[0],toEndpoint:e[1],options:c}))),m=e.map(e.pick(["distance","time","steps","navline","waypoints"]),r);return{total:{distance:e.sum(e.map(e=>e.distance,m)),time:e.sum(e.map(e=>e.time,m))},directions:m}}),i.bus.on("clientAPI/getPOIDetails",async({poiId:e})=>i.bus.get("poi/getById",{id:e})),i.bus.on("clientAPI/getAllPOIs",async()=>i.bus.get("poi/getAll")),i.bus.on("clientAPI/getStructures",()=>n(i)),i.bus.on("clientAPI/getSecurityWaitTimes",async({isOpen:e})=>i.bus.get("dynamicPois/getSecurityWaitTimes",{isOpen:e}));const s=e=>"function"!=typeof e;i.bus.on("clientAPI/getVenueData",async()=>{const t=await i.bus.get("venueData/getVenueData");return e.filter(s,t)}),i.bus.on("clientAPI/search",async({term:e,details:t})=>i.bus.get("search/queryAsync",{term:e}).then(n=>{const s=n.map(e=>e.poiId);return i.bus.send("event/search",{referrer:"prog",searchMethod:null,query:e,entities:s}),t?n:s})),i.bus.on("clientAPI/getFlightStatus",async({term:e,type:t="all"})=>i.bus.get("flightStatus/query",{term:e,type:t}))}export{s as handleHeadless,i as headlessCommands};
@@ -1 +1 @@
1
- var a="SDK headless",e={monitoring:{applicationInsights:{}},analytics2:{productName:"LocusMaps JS SDK",active:!1,disableSending:!1},clientAPI:{},dynamicPois:{},poiDataManager:{},sdkServer:{},searchService:{},venueDataLoader:{assetStage:"prod",formatVersion:"v5",availableLanguages:[{langCode:"en",assetSuffix:""}]},wayfinder:{compareFindPaths:!1}},i={name:a,plugins:e};export{i as default,a as name,e as plugins};
1
+ var a="SDK headless",e={monitoring:{applicationInsights:{}},analytics2:{productName:"LocusMaps JS SDK",active:!1,disableSending:!1},clientAPI:{},dynamicPois:{},flightStatus:{},poiDataManager:{},sdkServer:{},searchService:{},venueDataLoader:{assetStage:"prod",formatVersion:"v5",availableLanguages:[{langCode:"en",assetSuffix:""}]},wayfinder:{compareFindPaths:!1}},i={name:a,plugins:e};export{i as default,a as name,e as plugins};
@@ -0,0 +1 @@
1
+ import{DateTime as e}from"luxon";const o=(o,t="en")=>(o instanceof Date&&(o=e(o)),"is"===t&&(t="ca"),o.setLocale(t).toLocaleString(e.TIME_SIMPLE)),t=e=>Math.ceil(e/60/1e3);export{o as formatTime,t as msToMin};
@@ -0,0 +1 @@
1
+ const E={ON_TIME:1,EARLY:2,DELAYED:3,CANCELLED:4,ARRIVED:5,DEPARTED:6,UNKNOWN:7};export{E as FlightLabelStatus};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atriusmaps-node-sdk",
3
- "version": "3.3.834",
3
+ "version": "3.3.836",
4
4
  "description": "This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information",
5
5
  "keywords": [
6
6
  "map",