+6
-2
server/src/index.ts
+6
-2
server/src/index.ts
···
1
1
import root from "./root.ts";
2
2
import user from "./user.ts";
3
+
import backfill from "./backfill.ts";
4
+
import { routes } from "./db/schema.ts";
3
5
4
6
const ROOT_DOMAIN = Deno.env.get("HOSTNAME") || "localhost";
5
7
const PORT = Number(Deno.env.get("PORT")) || 80;
···
19
21
}
20
22
return head;
21
23
}
24
+
25
+
const db = await backfill();
22
26
23
27
Deno.serve({ port: PORT, hostname: ROOT_DOMAIN }, async (req) => {
24
28
const reqUrl = new URL(req.url);
···
42
46
// did:web example: `vielle.dev.did-web.ROOT_DOMAIN
43
47
// last segment must be did-plc or did-web
44
48
if (subdomain.at(-1)?.match(/^did-(web|plc)+$/gm)) {
45
-
const res = await user(req, {
49
+
const res = await user(db, req, {
46
50
did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${subdomain.slice(0, -1).join(".")}`,
47
51
});
48
52
return new Response(res.body, {
···
60
64
// ex: vielle.dev.ROOT_DOMAIN
61
65
// cannot contain hyphen in top level domain
62
66
if (!subdomain.at(-1)?.startsWith("did-") && subdomain.length > 1) {
63
-
const res = await user(req, {
67
+
const res = await user(db, req, {
64
68
handle: subdomain.join(".") as `${string}.${string}`,
65
69
});
66
70
return new Response(res.body, {
+7
server/src/types.ts
+7
server/src/types.ts
+41
server/src/user.ts
+41
server/src/user.ts
···
10
10
WebDidDocumentResolver,
11
11
} from "@atcute/identity-resolver";
12
12
import { DevAtcitiesRoute } from "./lexicons/index.ts";
13
+
import { db } from "./types.ts";
14
+
import { and, eq } from "drizzle-orm";
15
+
import { routes } from "./db/schema.ts";
13
16
14
17
const handleResolver = new CompositeHandleResolver({
15
18
strategy: "race",
···
240
243
}
241
244
242
245
export default async function (
246
+
db: db,
243
247
req: Request,
244
248
user:
245
249
| { handle: `${string}.${string}` }
···
258
262
});
259
263
}
260
264
} else did = user.did;
265
+
266
+
// look up in db
267
+
const db_res =
268
+
(
269
+
await db
270
+
.select()
271
+
.from(routes)
272
+
.where(
273
+
and(
274
+
eq(routes.did, did),
275
+
eq(routes.url_route, new URL(req.url).pathname)
276
+
)
277
+
)
278
+
).at(0) ??
279
+
(
280
+
await db
281
+
.select()
282
+
.from(routes)
283
+
.where(and(eq(routes.did, did), eq(routes.url_route, "404")))
284
+
).at(0);
285
+
286
+
if (db_res) {
287
+
try {
288
+
const file = await Deno.readFile(
289
+
`./blobs/${db_res.did}/${db_res.blob_cid}`
290
+
);
291
+
return new Response(file, {
292
+
headers: {
293
+
"Content-Type": db_res.mime,
294
+
},
295
+
});
296
+
} catch {
297
+
return new Response(
298
+
"Could not find in CDN; TODO: fallback to fetch from pds && add to cdn if missing\nNB: should this be default? index routes in db but only cache used pages"
299
+
);
300
+
}
301
+
}
261
302
262
303
// resolve did doc
263
304
let doc;