You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.7 KiB
TypeScript

import { serve as serveHttp } from "./deps/http.ts";
import {
compressResponse,
setHeaders,
orElse,
filter,
catching,
log,
} from "./deps/shirt.ts";
import { frontend } from "../build/frontend.ts";
import { style } from "../build/style.ts";
import { serve } from "./api.ts";
import { load as loadConfiguration } from "./config.ts";
export const notFound = (_req: Request) => {
return new Response("Not found", { status: 404 });
}
const internalServerError = (_req: Request, e: unknown) => {
console.error(e);
return new Response("Something went wrong", { status: 500 });
}
const apiHandler = filter(
(req) => new URL(req.url).pathname.split("/")[1] === "api",
setHeaders([["content-type", "application/json"]], serve),
);
const root = async (req: Request) => {
if (!req.url.endsWith("/")) {
return null;
}
const config = await loadConfiguration();
return new Response(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="${config.description ?? config.title ?? "Statue - a simple status monitor"}">
<script type="module">
${frontend}
</script>
<style>
${style}
</style>
<title>${config.title ?? "Statue"}</title>
</head>
<body>
<noscript>
You need to enable JavaScript to view this page.
</noscript>
</body>
</html>
`, {
headers: { "content-type": "text/html; charset=utf-8" },
});
};
const listener =
log(compressResponse(catching(orElse(
apiHandler,
orElse(root, notFound),
), internalServerError)));
const config = await loadConfiguration();
const port = config.port ?? 8888;
const host = config.hostname ?? "127.0.0.1";
const server = serveHttp(listener, {
hostname: host,
port,
});
await server;