UNPKG

@windingtree/wt-read-api

Version:

API to interact with the Winding Tree platform

145 lines (139 loc) 5.32 kB
const { mapAirlineFieldsFromQuery } = require('../services/property-mapping'); const { flattenObject, formatError } = require('../services/utils'); const { Http404Error, HttpBadGatewayError, HttpValidationError } = require('../errors'); const { DataFormatValidator } = require('../services/validation'); const { config } = require('../config'); const { VALIDATION_WARNING_HEADER, SCHEMA_PATH, FLIGHT_MODEL, } = require('../constants'); const find = async (req, res, next) => { const fieldsQuery = req.query.fields || []; let fieldsArray = Array.isArray(fieldsQuery) ? fieldsQuery : fieldsQuery.split(','); fieldsArray = mapAirlineFieldsFromQuery(fieldsArray); const { flightId } = req.params; try { const loadInstances = fieldsArray.indexOf('flightInstancesUri') > -1; const fieldsToResolve = loadInstances ? ['flightsUri.items.flightInstancesUri'] : ['flightsUri.items']; const depth = loadInstances ? undefined : 2; const airlineApis = await res.locals.wt.airline.getWindingTreeApi(); const apiContents = (await airlineApis.airline[0].toPlainObject(fieldsToResolve, depth)).contents; if (!apiContents.flightsUri) { return next(new Http404Error('flightNotFound', 'Flights not found')); } const flights = apiContents.flightsUri.contents; const flight = flights.items.find(f => f.id === flightId); if (!flight) { return next(new Http404Error('flightNotFound', 'Flight not found')); } const flattenedFlight = flattenObject(flight, fieldsArray); flight.flightInstances = flattenedFlight.flightInstancesUri; delete flight.flightInstancesUri; const swaggerDocument = await DataFormatValidator.loadSchemaFromPath(SCHEMA_PATH, FLIGHT_MODEL); try { DataFormatValidator.validate( flight, FLIGHT_MODEL, swaggerDocument.components.schemas, config.dataFormatVersions.airlines, apiContents.dataFormatVersion, 'flight', ); } catch (e) { if (e instanceof HttpValidationError) { const err = formatError(e); err.data = flight; if (e.data && e.data.valid) { return res.set(VALIDATION_WARNING_HEADER, e.data.errors).status(200).json(err.toPlainObject()); } else { return res.status(err.status).json(err.toPlainObject()); } } else { next(e); } } res.status(200).json(flight); } catch (e) { next(e); } }; const findAll = async (req, res, next) => { const fieldsQuery = req.query.fields || []; let fieldsArray = Array.isArray(fieldsQuery) ? fieldsQuery : fieldsQuery.split(','); fieldsArray = mapAirlineFieldsFromQuery(fieldsArray); try { const loadInstances = fieldsArray.indexOf('flightInstancesUri') > -1; const fieldsToResolve = loadInstances ? ['flightsUri.items.flightInstancesUri'] : ['flightsUri.items']; const depth = loadInstances ? undefined : 2; const airlineApis = await res.locals.wt.airline.getWindingTreeApi(); const apiContents = (await airlineApis.airline[0].toPlainObject(fieldsToResolve, depth)).contents; if (!apiContents.flightsUri) { return next(new Http404Error('flightNotFound', 'Flights not found')); } const flights = [], warnings = [], errors = []; const swaggerDocument = await DataFormatValidator.loadSchemaFromPath(SCHEMA_PATH, FLIGHT_MODEL); for (const flight of apiContents.flightsUri.contents.items) { const flattenedFlight = flattenObject(flight, fieldsArray); flight.flightInstances = flattenedFlight.flightInstancesUri; delete flight.flightInstancesUri; try { DataFormatValidator.validate( flight, FLIGHT_MODEL, swaggerDocument.components.schemas, config.dataFormatVersions.airlines, apiContents.dataFormatVersion, 'flight', ); flights.push(flight); } catch (e) { if (e instanceof HttpValidationError) { const err = formatError(e); err.data = flight; if (e.data && e.data.valid) { warnings.push(err); } else { err.data = { id: err.data.id }; errors.push(err); } } else { next(e); } } } res.status(200).json({ items: flights, warnings: warnings, errors: errors, updatedAt: apiContents.flightsUri.contents.updatedAt, }); } catch (e) { next(e); } }; const meta = async (req, res, next) => { const { flightId } = req.params; try { const airlineApis = await res.locals.wt.airline.getWindingTreeApi(); const apiContents = (await airlineApis.airline[0].toPlainObject(['flightsUri'])).contents; if (!apiContents.flightsUri) { return next(new Http404Error('flightNotFound', 'Flights not found')); } const flights = apiContents.flightsUri.contents; const flight = flights.items.find(f => f.id === flightId); if (!flight) { return next(new Http404Error('flightNotFound', 'Flight not found')); } res.status(200).json({ flightInstancesUri: flight.flightInstancesUri.ref, }); } catch (e) { return next(new HttpBadGatewayError('airlineNotAccessible', e.message, 'Airline data is not accessible.')); } }; module.exports = { find, findAll, meta, };