@windingtree/wt-read-api
Version:
API to interact with the Winding Tree platform
145 lines (139 loc) • 5.32 kB
JavaScript
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,
};