an attempt to make a lightweight, easily self-hostable, scoped bluesky appview
1import { parse } from "jsr:@std/jsonc";
2import * as z from "npm:zod";
3
4// configure these from the config.jsonc file (you can use config.jsonc.example as reference)
5export const indexTarget = z.string().refine(
6 (val) => {
7 const parts = val.split("#");
8 if (parts.length !== 2) return false;
9
10 const [prefix, suffix] = parts;
11 const validPrefix = prefix === "user" || prefix.startsWith("did:web:");
12 const validSuffix = suffix === "skylite_index" || suffix === "bsky_appview";
13
14 return validPrefix && validSuffix;
15 },
16 {
17 message:
18 "Each indexPriority entry must be in the form 'user#skylite_index', 'user#bsky_appview', 'did:web:...#skylite_index', or 'did:web:...#bsky_appview'",
19 }
20);
21
22const ConfigSchema = z.object({
23 jetstream: z.string(),
24 spacedust: z.string(),
25 constellation: z.string(),
26 slingshot: z.string(),
27 indexServer: z.object({
28 inviteOnly: z.boolean(),
29 port: z.number(),
30 did: z.string(),
31 host: z.string(),
32 }),
33 viewServer: z.object({
34 inviteOnly: z.boolean(),
35 port: z.number(),
36 did: z.string(),
37 host: z.string(),
38 indexPriority: z.array(indexTarget),
39 }),
40});
41
42const raw = await Deno.readTextFile("config.jsonc");
43const config = ConfigSchema.parse(parse(raw));
44
45export { config };