[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!
1import root from "./root.ts";
2import user from "./user.ts";
3
4const ROOT_DOMAIN = Deno.env.get("HOSTNAME") || "localhost";
5const PORT = Number(Deno.env.get("PORT")) || 80;
6
7const SUBDOMAIN_REGEX = new RegExp(`.+(?=\\.${ROOT_DOMAIN}$)`, "gm");
8
9Deno.serve({ port: PORT, hostname: ROOT_DOMAIN }, async (req) => {
10 const reqUrl = new URL(req.url);
11 const subdomain = reqUrl.hostname.match(SUBDOMAIN_REGEX)?.at(0)?.split(".");
12
13 // redirect ROOT_DOMAIN => www.ROOT_DOMAIN
14 if (!subdomain) {
15 const redirUrl = new URL(reqUrl.toString());
16 redirUrl.host = "www." + redirUrl.host;
17 return new Response(`Redirecting to ${redirUrl.toString()}`, {
18 status: 308,
19 headers: {
20 Location: redirUrl.toString(),
21 },
22 });
23 }
24
25 if (subdomain.length === 1 && subdomain[0] === "www") return root(req);
26
27 // did:plc example: `sjkdgfjk.did-plc.ROOT_DOMAIN`
28 // did:web example: `vielle.dev.did-web.ROOT_DOMAIN
29 // last segment must be did-plc or did-web
30 if (subdomain.at(-1)?.match(/^did-(web|plc)+$/gm)) {
31 return user(req, {
32 did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${subdomain.slice(0, -1).join(".")}`,
33 });
34 }
35
36 // ex: vielle.dev.ROOT_DOMAIN
37 // cannot contain hyphen in top level domain
38 if (!subdomain.at(-1)?.startsWith("did-") && subdomain.length > 1) {
39 return await user(req, {
40 handle: subdomain.join(".") as `${string}.${string}`,
41 });
42 }
43
44 return new Response(
45 `Could not resolve domain "${subdomain.join(".")}.${ROOT_DOMAIN}"`,
46 {
47 status: 404,
48 }
49 );
50});