import { readFileSync } from "fs"; import { ApolloServer } from "@apollo/server"; import { MergedResolvers } from "./MergedResolvers"; import { ServerContext } from "./ServerContext"; import { InterchangeSystem, InterchangeSystemBuilderArguments } from "./entities/InterchangeSystem"; import { ChapmanApiBasedParkingRepositoryLoader } from "./loaders/parking/ChapmanApiBasedParkingRepositoryLoader"; import express from "express"; import { expressMiddleware } from "@as-integrations/express5"; import { RATE_LIMIT_DELAY_AFTER_REQUESTS, RATE_LIMIT_DELAY_MULTIPLIER_MS, RATE_LIMIT_WINDOW_MS, RATE_LIMITS_DISABLED } from "./environment"; import slowDown from "express-slow-down"; const typeDefs = readFileSync("./schema.graphqls", "utf8"); // In the future this can be stored as a separate file const supportedSystems: InterchangeSystemBuilderArguments[] = [ { id: "1", passioSystemId: "263", parkingSystemId: ChapmanApiBasedParkingRepositoryLoader.id, name: "Chapman University", useSelfUpdatingEtas: true, } ] async function main() { const server = new ApolloServer({ typeDefs, resolvers: MergedResolvers, introspection: process.env.NODE_ENV !== "production", }); await server.start(); let systems: InterchangeSystem[]; systems = await Promise.all(supportedSystems.map( async (systemArguments) => { return await InterchangeSystem.build(systemArguments); }, )); const app = express(); const options = { context: async () => { return { systems, findSystemById: (id: string) => { const system = systems.find((system) => system.id === id); if (!system) { return null; } return system; }, } }, }; if (RATE_LIMITS_DISABLED) { app.use( "/", express.json(), expressMiddleware(server, options) ); } else { const limiter = slowDown({ windowMs: RATE_LIMIT_WINDOW_MS, delayAfter: RATE_LIMIT_DELAY_AFTER_REQUESTS, delayMs: (hits) => { return hits * RATE_LIMIT_DELAY_MULTIPLIER_MS; } }); app.use( "/", express.json(), limiter, expressMiddleware(server, options), ); } const port = process.env.PORT ? parseInt(process.env.PORT) : 4000; app.listen(port, () => { console.log(`Server ready at port ${port}`); }); } main();