diff --git a/src/MergedResolvers.ts b/src/MergedResolvers.ts index b5b56b2..bfa40eb 100644 --- a/src/MergedResolvers.ts +++ b/src/MergedResolvers.ts @@ -1,205 +1,19 @@ import { Coordinates, Eta, OrderedStop, Resolvers } from "./generated/graphql"; import { ServerContext } from "./ServerContext"; import { QueryResolvers } from "./resolvers/QueryResolvers"; +import { SystemResolvers } from "./resolvers/SystemResolvers"; +import { EtaResolvers } from "./resolvers/EtaResolvers"; +import { OrderedStopResolvers } from "./resolvers/OrderedStopResolvers"; +import { StopResolvers } from "./resolvers/StopResolvers"; +import { ShuttleResolvers } from "./resolvers/ShuttleResolvers"; +import { RouteResolvers } from "./resolvers/RouteResolvers"; export const MergedResolvers: Resolvers = { ...QueryResolvers, - System: { - routes: async (parent, args, contextValue, info) => { - return await contextValue.repository.getRoutesBySystemId(parent.id); - }, - 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 shuttle; - }, - shuttles: async (parent, args, contextValue, info) => { - const shuttles = await contextValue.repository.getShuttlesBySystemId(parent.id); - - return shuttles.map(shuttle => ({ - coordinates: shuttle.coordinates, - name: shuttle.name, - id: shuttle.id, - routeId: shuttle.routeId, - })); - } - }, - 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, - routeId: parent.id, - id, - })); - }, - orderedStop: async (parent, args, contextValue, info) => { - if (!args.forStopId) return null; - const orderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(parent.id, args.forStopId); - if (!orderedStop) return null; - - const stop = await contextValue.repository.getStopById(orderedStop.stopId); - if (!stop) return null; - - return { - stopId: args.forStopId, - routeId: parent.id, - route: parent, - } - }, - }, - Shuttle: { - eta: async (parent, args, contextValue, info) => { - if (!args.forStopId) return null; - const etaForStopId = await contextValue.repository.getEtaForShuttleAndStopId(parent.id, args.forStopId); - if (etaForStopId === null) return null; - - return { - stopId: args.forStopId, - secondsRemaining: etaForStopId.secondsRemaining, - shuttleId: parent.id, - shuttle: parent, - }; - }, - 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 => { - return { - secondsRemaining, - stopId, - shuttle: parent, - shuttleId: parent.id, - } - })); - - if (computedEtas.every((eta) => eta !== null)) { - return computedEtas; - } - - return []; - }, - route: async (parent, args, contextValue, info) => { - const route = await contextValue.repository.getRouteById(parent.routeId); - if (route === null) return null; - - return { - color: route.color, - id: route.id, - name: route.name, - polylineCoordinates: route.polylineCoordinates, - } - } - }, - Stop: { - orderedStops: async (parent, args, contextValue, info) => { - return await contextValue.repository.getOrderedStopsByStopId(parent.id); - }, - etas: async (parent, args, contextValue, info) => { - return await contextValue.repository.getEtasForStopId(parent.id); - }, - }, - OrderedStop: { - nextStop: async (parent, args, contextValue, info): Promise => { - const routeId = parent.routeId; - const stopId = parent.stopId; - - const currentOrderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(routeId, stopId); - if (!currentOrderedStop) return null; - - const nextOrderedStop = currentOrderedStop.nextStop; - if (!nextOrderedStop) return null; - - const nextOrderedStopObject = await contextValue.repository.getStopById(nextOrderedStop.stopId); - if (!nextOrderedStopObject) return null; - - return { - route: parent.route, - routeId: parent.routeId, - stopId: nextOrderedStopObject.id, - } - }, - previousStop: async (parent, args, contextValue, info): Promise => { - const routeId = parent.routeId; - const stopId = parent.stopId; - - const currentOrderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(routeId, stopId); - if (!currentOrderedStop) return null; - - const previousOrderedStop = currentOrderedStop.previousStop; - if (!previousOrderedStop) return null; - - const previousOrderedStopObject = await contextValue.repository.getStopById(previousOrderedStop.stopId); - if (!previousOrderedStopObject) return null; - - return { - route: parent.route, - routeId: parent.routeId, - stopId: previousOrderedStopObject.id, - } - }, - stop: async (parent, args, contextValue, info) => { - return await contextValue.repository.getStopById(parent.stopId); - }, - route: async (parent, args, contextValue, info) => { - return await contextValue.repository.getRouteById(parent.routeId); - }, - }, - ETA: { - stop: async (parent, args, contextValue, info) => { - return await contextValue.repository.getStopById(parent.stopId); - }, - shuttle: async (parent, args, contextValue, info) => { - return await contextValue.repository.getShuttleById(parent.shuttleId); - }, - }, + ...SystemResolvers, + ...RouteResolvers, + ...ShuttleResolvers, + ...StopResolvers, + ...OrderedStopResolvers, + ...EtaResolvers, }; \ No newline at end of file diff --git a/src/resolvers/EtaResolvers.ts b/src/resolvers/EtaResolvers.ts new file mode 100644 index 0000000..96bd426 --- /dev/null +++ b/src/resolvers/EtaResolvers.ts @@ -0,0 +1,13 @@ +import { Resolvers } from "../generated/graphql"; +import { ServerContext } from "../ServerContext"; + +export const EtaResolvers: Resolvers = { + ETA: { + stop: async (parent, args, contextValue, info) => { + return await contextValue.repository.getStopById(parent.stopId); + }, + shuttle: async (parent, args, contextValue, info) => { + return await contextValue.repository.getShuttleById(parent.shuttleId); + }, + }, +} \ No newline at end of file diff --git a/src/resolvers/OrderedStopResolvers.ts b/src/resolvers/OrderedStopResolvers.ts new file mode 100644 index 0000000..ad6c8e6 --- /dev/null +++ b/src/resolvers/OrderedStopResolvers.ts @@ -0,0 +1,52 @@ +import { OrderedStop, Resolvers } from "../generated/graphql"; +import { ServerContext } from "../ServerContext"; + +export const OrderedStopResolvers: Resolvers = { + OrderedStop: { + nextStop: async (parent, args, contextValue, info): Promise => { + const routeId = parent.routeId; + const stopId = parent.stopId; + + const currentOrderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(routeId, stopId); + if (!currentOrderedStop) return null; + + const nextOrderedStop = currentOrderedStop.nextStop; + if (!nextOrderedStop) return null; + + const nextOrderedStopObject = await contextValue.repository.getStopById(nextOrderedStop.stopId); + if (!nextOrderedStopObject) return null; + + return { + route: parent.route, + routeId: parent.routeId, + stopId: nextOrderedStopObject.id, + } + }, + previousStop: async (parent, args, contextValue, info): Promise => { + const routeId = parent.routeId; + const stopId = parent.stopId; + + const currentOrderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(routeId, stopId); + if (!currentOrderedStop) return null; + + const previousOrderedStop = currentOrderedStop.previousStop; + if (!previousOrderedStop) return null; + + const previousOrderedStopObject = await contextValue.repository.getStopById(previousOrderedStop.stopId); + if (!previousOrderedStopObject) return null; + + return { + route: parent.route, + routeId: parent.routeId, + stopId: previousOrderedStopObject.id, + } + }, + stop: async (parent, args, contextValue, info) => { + return await contextValue.repository.getStopById(parent.stopId); + }, + route: async (parent, args, contextValue, info) => { + return await contextValue.repository.getRouteById(parent.routeId); + }, + }, + +} \ No newline at end of file diff --git a/src/resolvers/RouteResolvers.ts b/src/resolvers/RouteResolvers.ts new file mode 100644 index 0000000..94dc13f --- /dev/null +++ b/src/resolvers/RouteResolvers.ts @@ -0,0 +1,36 @@ +import { Coordinates, Resolvers } from "../generated/graphql"; +import { ServerContext } from "../ServerContext"; + +export const RouteResolvers: Resolvers = { + 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, + routeId: parent.id, + id, + })); + }, + orderedStop: async (parent, args, contextValue, info) => { + if (!args.forStopId) return null; + const orderedStop = await contextValue.repository.getOrderedStopByRouteAndStopId(parent.id, args.forStopId); + if (!orderedStop) return null; + + const stop = await contextValue.repository.getStopById(orderedStop.stopId); + if (!stop) return null; + + return { + stopId: args.forStopId, + routeId: parent.id, + route: parent, + } + }, + }, +} \ No newline at end of file diff --git a/src/resolvers/ShuttleResolvers.ts b/src/resolvers/ShuttleResolvers.ts new file mode 100644 index 0000000..2350987 --- /dev/null +++ b/src/resolvers/ShuttleResolvers.ts @@ -0,0 +1,52 @@ +import { Eta, Resolvers } from "../generated/graphql"; +import { ServerContext } from "../ServerContext"; + +export const ShuttleResolvers: Resolvers = { + Shuttle: { + eta: async (parent, args, contextValue, info) => { + if (!args.forStopId) return null; + const etaForStopId = await contextValue.repository.getEtaForShuttleAndStopId(parent.id, args.forStopId); + if (etaForStopId === null) return null; + + return { + stopId: args.forStopId, + secondsRemaining: etaForStopId.secondsRemaining, + shuttleId: parent.id, + shuttle: parent, + }; + }, + 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 => { + return { + secondsRemaining, + stopId, + shuttle: parent, + shuttleId: parent.id, + } + })); + + if (computedEtas.every((eta) => eta !== null)) { + return computedEtas; + } + + return []; + }, + route: async (parent, args, contextValue, info) => { + const route = await contextValue.repository.getRouteById(parent.routeId); + if (route === null) return null; + + return { + color: route.color, + id: route.id, + name: route.name, + polylineCoordinates: route.polylineCoordinates, + } + } + }, +} \ No newline at end of file diff --git a/src/resolvers/StopResolvers.ts b/src/resolvers/StopResolvers.ts new file mode 100644 index 0000000..6ccbdf1 --- /dev/null +++ b/src/resolvers/StopResolvers.ts @@ -0,0 +1,13 @@ +import { Resolvers } from "../generated/graphql"; +import { ServerContext } from "../ServerContext"; + +export const StopResolvers: Resolvers = { + Stop: { + orderedStops: async (parent, args, contextValue, info) => { + return await contextValue.repository.getOrderedStopsByStopId(parent.id); + }, + etas: async (parent, args, contextValue, info) => { + return await contextValue.repository.getEtasForStopId(parent.id); + }, + }, +} \ No newline at end of file diff --git a/src/resolvers/SystemResolvers.ts b/src/resolvers/SystemResolvers.ts new file mode 100644 index 0000000..b78e922 --- /dev/null +++ b/src/resolvers/SystemResolvers.ts @@ -0,0 +1,63 @@ +import { Coordinates, Resolvers } from "../generated/graphql"; +import { ServerContext } from "../ServerContext"; + +export const SystemResolvers: Resolvers = { + System: { + routes: async (parent, args, contextValue, info) => { + return await contextValue.repository.getRoutesBySystemId(parent.id); + }, + 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 shuttle; + }, + shuttles: async (parent, args, contextValue, info) => { + const shuttles = await contextValue.repository.getShuttlesBySystemId(parent.id); + + return shuttles.map(shuttle => ({ + coordinates: shuttle.coordinates, + name: shuttle.name, + id: shuttle.id, + routeId: shuttle.routeId, + })); + } + }, +} \ No newline at end of file