Files
scoresaber-reloaded-backend/src/server/server.ts

109 lines
2.5 KiB
TypeScript

import express, { Express } from "express";
import { ServerMessages } from "../route/messages";
import { Route } from "../route/route";
type ServerConfig = {
port: number;
routes?: Route[];
};
export default class Server {
/**
* The port that this server is listening on.
*/
private port: number;
/**
* The express server.
*/
private server: Express;
/**
* The routes that this server is serving.
*/
private routes: Route[] = [];
constructor({ port, routes }: ServerConfig) {
this.port = port;
if (routes) {
this.routes.push(...routes);
}
// Create the express server
this.server = express();
this.preInit();
// Setup route logging
this.server.use((req, res, next) => {
// TODO: make this look better?
console.log(`[${req.method}] ${req.path}`);
next();
});
// Handle the routes
for (const route of this.routes) {
this.server.all(route.getPath(), (req, res, next) => {
if (req.method.toUpperCase() !== route.getMethod().toUpperCase()) {
return next(); // Skip this method
}
try {
route.handle(req, res, next);
} catch (ex) {
console.error(ex);
// Inform the user that an internal server error occurred
res.status(500).json(ServerMessages.internalServerError());
}
});
}
// Log the registered routes
console.log(`Registered ${this.routes.length} routes`);
for (const route of this.routes) {
console.log(` - ${route.getMethod().toUpperCase()} ${route.getPath()}`);
}
// Handle unknown routes
this.server.all("*", (req, res) => {
res.status(404).send("404 Not Found");
});
// Start listening on the specified port
this.server.listen(this.port, () => {
console.log(`Server listening on http://localhost:${this.port}`);
this.postInit();
});
}
/**
* Returns the port that this server is listening on.
*
* @returns {number} the port
*/
public getPort() {
return this.port;
}
/**
* Registers a list of routes.
*
* @param route the routes to register
*/
public registerRoute(...routes: Route[]) {
this.routes.push(...routes);
}
public getRoute(path: string): Route | undefined {
return this.routes.find((route) => route.getPath() === path);
}
/**
* Gets called before the server starts listening.
*/
public preInit(): void {}
/**
* Gets called after the server starts listening.
*/
public postInit(): void {}
}