All files / src server.ts

100% Statements 36/36
100% Branches 2/2
100% Functions 14/14
100% Lines 36/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 1132x       2x 2x 2x 2x 2x                 9x                               9x         9x 9x 9x 9x 9x   9x 3x         3x 3x   3x       3x   3x       5x       3x       2x       2x             3x 3x   3x       3x   3x 33x     3x 1x     2x       6x       3x       2x  
import HTTP from 'http';
 
import Route from 'route';
import Adapter from 'interface/adapter';
import Repository from 'repository';
import closeServer from 'http/utility/close-server';
import buildRoutes from 'server/utility/build-routes';
import MemoryAdapter from 'adapter/memory';
import PlaintextNotFoundRoute from 'route/plaintext/not-found';
 
interface ServerConfig {
	readonly port: number;
	readonly adapter: Adapter;
	readonly hostname: string;
}
 
function buildDefaultConfig(): ServerConfig {
	return {
		port: 9999,
		adapter: new MemoryAdapter(),
		hostname: 'http://localhost'
	};
}
 
class Server {
	private port: number;
	private adapter: Adapter;
	private hostname: string;
	private repository: Repository;
	private server: HTTP.Server;
	private routes: Route[];
 
	public constructor(partial_config?: Partial<ServerConfig>) {
		const config: ServerConfig = {
			...buildDefaultConfig(),
			...partial_config
		};
 
		this.port = config.port;
		this.hostname = config.hostname;
		this.adapter = config.adapter;
		this.repository = new Repository(config.hostname, config.adapter);
		this.routes = buildRoutes();
 
		this.server = HTTP.createServer((request, response) => {
			this.handleRequest(request, response);
		});
	}
 
	public start(): void {
		const port = this.getPort();
		const server = this.getServer();
 
		server.listen(port);
	}
 
	public stop(): Promise<void> {
		const server = this.getServer();
 
		return closeServer(server);
	}
 
	public getPort(): number {
		return this.port;
	}
 
	public getRepository(): Repository {
		return this.repository;
	}
 
	public getHostname(): string {
		return this.hostname;
	}
 
	public getAdapter(): Adapter {
		return this.adapter;
	}
 
	private handleRequest(
		request: HTTP.IncomingMessage,
		response: HTTP.ServerResponse
	): void {
		const route = this.findRouteForRequest(request);
		const repository = this.getRepository();
 
		route.serve(request, response, repository);
	}
 
	private findRouteForRequest(request: HTTP.IncomingMessage): Route {
		const routes = this.getRoutes();
 
		const route = routes.find((route) => {
			return route.accepts(request);
		});
 
		if (route === undefined) {
			return new PlaintextNotFoundRoute();
		}
 
		return route;
	}
 
	private getServer(): HTTP.Server {
		return this.server;
	}
 
	private getRoutes(): Route[] {
		return this.routes;
	}
}
 
export default Server;