import { Coordinates, Eta, OrderedStop, Resolvers, Route, Shuttle, Stop, System } from "./generated/graphql"; import { ServerContext } from "./serverContext"; export const resolvers: Resolvers = { Query: { systems: async (parent, args, contextValue, info) => { const systems = await contextValue.repository.getSystems(); return systems.map(({ name, id }) => ({ name, id })); }, system: async (parent, args, contextValue, info) => { if (!args.id) return null; const system = await contextValue.repository.getSystemById(args.id); if (system === null) return null; return { name: system.name, id: system.id, }; } }, System: { routes: async (parent, args, contextValue, info) => { const routes = await contextValue.repository.getRoutesBySystemId(parent.id); return routes.map(({ color, id, name, polylineCoordinates, }) => ({ color, id, name, polylineCoordinates, })); }, stops: async (parent, args, contextValue, info) => { const stops = await contextValue.repository.getStopsBySystemId(parent.id); return stops.map(({ id, name, coordinates }) => ({ id, name, // Both ICoordinates and Coordinates have the same definition coordinates: coordinates as Coordinates, })); }, stop: async (parent, args, contextValue, info) => { if (!args.id) return null; const stop = await contextValue.repository.getStopById(args.id); if (stop === null) return null; return { id: stop.id, name: stop.name, coordinates: stop.coordinates as Coordinates, }; }, route: async (parent, args, contextValue, info) => { if (!args.id) return null; const route = await contextValue.repository.getRouteById(args.id); if (route === null) return null; return { color: route.color, id: route.id, name: route.name, polylineCoordinates: route.polylineCoordinates as Coordinates[], }; }, shuttle: async (parent, args, contextValue, info) => { if (!args.id) return null; const shuttle = await contextValue.repository.getShuttleById(args.id); if (shuttle === null) return null; return { coordinates: shuttle.coordinates as Coordinates, id: shuttle.id, name: shuttle.name, }; } }, Route: { shuttles: async (parent, args, contextValue, info) => { const shuttles = await contextValue.repository.getShuttlesByRouteId(parent.id); return shuttles.map(({ coordinates, name, id, }) => ({ coordinates: coordinates as Coordinates, name, route: parent, id, })); } }, Shuttle: { eta: (parent, args, contextValue, info) => { const etaForNextStop = parent.etas?.find((eta) => eta.stop.id === args.forStopId); if (!etaForNextStop) { return null; } return etaForNextStop; }, etas: async (parent, args, contextValue, info) => { const etasForShuttle = await contextValue.repository.getEtasForShuttleId(parent.id); if (!etasForShuttle) return null; const computedEtas = await Promise.all(etasForShuttle.map(async ({ secondsRemaining, stopId, }): Promise => { const stop = await contextValue.repository.getStopById(stopId); if (stop === null) return null; return { secondsRemaining, stop: { coordinates: stop.coordinates, id: stop.id, name: stop.name, }, shuttle: parent, } })); if (computedEtas.every((eta) => eta !== null)) { return computedEtas; } return []; } }, Stop: { orderedStops: async (parent, args, contextValue, info) => { const orderedStops = await contextValue.repository.getOrderedStopsByStopId(parent.id); const computedOrderedStops = await Promise.all(orderedStops.map(async ({ routeId, stopId, }): Promise => { const stop = await contextValue.repository.getStopById(stopId); const route = await contextValue.repository.getRouteById(routeId); if (stop === null || route === null) return null; return { stop: { coordinates: stop.coordinates, id: stop.id, name: stop.name, }, route: { name: route.name, id: route.id, polylineCoordinates: route.polylineCoordinates, color: route.color, }, }; })); if (computedOrderedStops.every((value) => value !== null)) { return computedOrderedStops as OrderedStop[]; } return []; } }, OrderedStop: { nextStop: async (parent, args, contextValue, info): Promise => { const routeId = parent.route.id; const stopId = parent.stop.id; const currentOrderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(routeId, stopId); if (!currentOrderedStop) return null; const nextOrderedStop = currentOrderedStop.nextStop; if (!nextOrderedStop) return null; const nextStopObject = await contextValue.repository.getStopById(nextOrderedStop.stopId); if (!nextStopObject) return null; return { route: parent.route, stop: { coordinates: nextStopObject.coordinates as Coordinates, id: nextStopObject.id, name: nextStopObject.name, } } }, previousStop: async (parent, args, contextValue, info): Promise => { const routeId = parent.route.id; const stopId = parent.stop.id; const currentOrderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(routeId, stopId); if (!currentOrderedStop) return null; const previousOrderedStop = currentOrderedStop.previousStop; if (!previousOrderedStop) return null; const nextStopObject = await contextValue.repository.getStopById(previousOrderedStop.stopId); if (!nextStopObject) return null; return { route: parent.route, stop: { coordinates: nextStopObject.coordinates as Coordinates, id: nextStopObject.id, name: nextStopObject.name, } } }, }, };