import { Auth } from "./auth" import { Frontend } from "./frontend" export class Server { constructor() { this.auth = new Auth() this.frontend = new Frontend() } async getEnv(variables) { return Object.fromEntries( await Promise.all( variables.map(async variable => { const {state} = await Deno.permissions.query({ name: 'env', variable }) if (state === 'granted') { return [variable, Deno.env.get(variable)] } else { return [variable, undefined] } }) ) ) } async configure() { const env = await this.getEnv([ 'PORT', 'BASE_URL' ]) this.port = env.PORT ?? 3000 this.baseUrl = env.BASE_URL ?? '/macchiato' } async serveRequest(event) { const {pathname} = new URL(event.request.url) if (pathname === `${this.baseUrl}/api/auth`) { await this.auth.redirect(event) } else { await this.frontend.serve(event) } } async serveConn(conn) { const httpConn = Deno.serveHttp(conn) for await (const event of httpConn) { this.serveRequest(event) } } async serve() { await this.configure() this.server = Deno.listen({ port: this.port, }) for await (const conn of this.server) { this.serveConn(conn) } } }