import assertUnreachable from '../../lang/assertUnreachable'; import type express from 'express'; export type HttpRoute = string; export type RoutePath = string; export type RouteHandler = (request: express.Request, response: express.Response) => void | Promise; export class HttpRouteManager { private readonly _staticGETRoutes: Record; private readonly _getRoutes: Record; private readonly _postRoutes: Record; private readonly _putRoutes: Record; private readonly _deleteRoutes: Record; constructor() { this._staticGETRoutes = {}; this._getRoutes = {}; this._postRoutes = {}; this._putRoutes = {}; this._deleteRoutes = {}; } public registerStaticRoute(routePath: RoutePath, destination: string) { if (this._staticGETRoutes[routePath]) { throw new Error(`Error: Static route [${routePath}] is already defined`); } this._staticGETRoutes[routePath] = destination; } public register(verb: 'GET' | 'POST' | 'PUT' | 'DELETE', route: string, handler: RouteHandler) { const isRouteDefined = (routes: Record, routePath: string) => !!routes[routePath]; switch (verb) { case 'GET': if (isRouteDefined(this._getRoutes, route)) { throw new Error(`Error: Route [${route}] is already defined`); } this._getRoutes[route] = handler; break; case 'POST': if (isRouteDefined(this._postRoutes, route)) { throw new Error(`Error: Route [${route}] is already defined`); } this._postRoutes[route] = handler; break; case 'PUT': if (isRouteDefined(this._putRoutes, route)) { throw new Error(`Error: Route [${route}] is already defined`); } this._putRoutes[route] = handler; break; case 'DELETE': if (isRouteDefined(this._deleteRoutes, route)) { throw new Error(`Error: Route [${route}] is already defined`); } this._deleteRoutes[route] = handler; break; default: assertUnreachable(verb); } } public getStaticGETRoutes(): Record { return this._staticGETRoutes; } public getGETRoutes(): Record { return this._getRoutes; } public getPOSTRoutes(): Record { return this._postRoutes; } public getPUTRoutes(): Record { return this._putRoutes; } public getDELETERoutes(): Record { return this._deleteRoutes; } }