All files server.ts

97.14% Statements 34/35
50% Branches 1/2
100% Functions 14/14
97.14% Lines 34/35

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 1122x       2x 2x 2x 2x                 8x                               8x         8x 8x 8x 8x 8x   8x 2x         2x 2x   2x       2x   2x       4x       2x       2x       2x             2x 2x   2x       2x   2x 5x     2x       2x       4x       2x       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';
 
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);
		});
 
		Iif (route === undefined) {
			throw new Error(`No route found for request: ${request.url}`);
		}
 
		return route;
	}
 
	private getServer(): HTTP.Server {
		return this.server;
	}
 
	private getRoutes(): Route[] {
		return this.routes;
	}
}
 
export default Server;