A fullstack app for indexing standard.site documents
1/**
2 * Constructs a full URL to fetch a blob from a PDS.
3 * Format: {pds}/xrpc/com.atproto.sync.getBlob?did={did}&cid={cid}
4 */
5export function buildBlobUrl(pds: string, did: string, cid: string): string {
6 const baseUrl = pds.endsWith("/") ? pds.slice(0, -1) : pds;
7 return `${baseUrl}/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(did)}&cid=${encodeURIComponent(cid)}`;
8}
9
10/**
11 * Extracts the CID from a blob reference object.
12 * Blob refs can be in different formats:
13 * - { $link: "cid" } (legacy)
14 * - { ref: { $link: "cid" } } (current)
15 * - { cid: "cid" } (simple)
16 */
17export function extractBlobCid(blob: unknown): string | null {
18 if (!blob || typeof blob !== "object") return null;
19
20 const b = blob as Record<string, unknown>;
21
22 // Current format: { ref: { $link: "cid" } }
23 if (b.ref && typeof b.ref === "object") {
24 const ref = b.ref as Record<string, unknown>;
25 if (typeof ref.$link === "string") return ref.$link;
26 }
27
28 // Legacy format: { $link: "cid" }
29 if (typeof b.$link === "string") return b.$link;
30
31 // Simple format: { cid: "cid" }
32 if (typeof b.cid === "string") return b.cid;
33
34 return null;
35}