char-slop/stars.hackery.site

git clone https://git.t4t.associates/char-slop/stars.hackery.site

Charlotte Somuse @cerulea/lexicon 0.2.0 and its typed format schemas8463413

main
1.7 KiB45 linesraw
1import * as l from "@cerulea/lexicon";
2
3export const Star = l.record("site.hackery.stars.star", { key: "tid" }, {
4  url: l.stringWith({ format: "uri", maxLength: 2048 }),
5  title: l.optional(l.stringWith({ maxLength: 2048 })),
6  comment: l.optional(l.stringWith({ maxGraphemes: 32768 })),
7  createdAt: l.datetime,
8});
9export type Star = l.Infer<typeof Star>;
10
11export const Follow = l.record("site.hackery.stars.follow", { key: "tid" }, {
12  subject: l.did,
13  createdAt: l.datetime,
14});
15export type Follow = l.Infer<typeof Follow>;
16
17export const Profile = l.object({
18  avatar: l.optional(
19    l.blob({ accept: ["image/png", "image/jpeg", "image/webp", "image/gif"] }),
20  ),
21});
22
23// A star's link as it will be stored: a bare http(s) URL short enough for the record.
24export function starUrl(raw: string | undefined): string | undefined {
25  const url = URL.parse(raw ?? "");
26  const usable = url && ["http:", "https:"].includes(url.protocol) &&
27    url.hostname && !url.username && !url.password && url.href.length <= 2048;
28  return usable ? url.href : undefined;
29}
30
31export type Did = `did:${string}:${string}`;
32// Only PLC and web DIDs can be resolved here.
33export const isDid = (value: string | undefined): value is Did =>
34  /^did:(plc|web):[a-zA-Z0-9.:%_-]+$/.test(value ?? "");
35
36export type AtUri = { did: string; collection: string; rkey: string };
37export const atUri = ({ did, collection, rkey }: AtUri) =>
38  `at://${did}/${collection}/${rkey}`;
39
40// Our collections all use TID keys, so anything else is rejected.
41export function parseAtUri(uri: string | undefined): AtUri | undefined {
42  const [, did, collection, rkey] =
43    /^at:\/\/(did:[^/]+)\/([^/]+)\/([234567a-z]{13})$/.exec(uri ?? "") ?? [];
44  if (did && l.atUri.validate(uri).success) return { did, collection, rkey };
45}