social components inlay.at
atproto components sdui
86
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 85 lines 2.2 kB view raw
1// data/xrpc.ts 2import "server-only"; 3import type { ComponentResponse } from "./types"; 4import { resolveDidToService } from "./resolve"; 5import { MissingError } from "@inlay/render"; 6 7/** 8 * Call a component's XRPC procedure endpoint (POST). 9 */ 10export async function callComponent( 11 did: string, 12 procedure: string, 13 input: Record<string, unknown>, 14 serviceJwt?: string 15): Promise<ComponentResponse> { 16 let url: string; 17 try { 18 const serviceUrl = await resolveDidToService(did, "#inlay"); 19 url = `${serviceUrl}/xrpc/${procedure}`; 20 } catch (e) { 21 throw new Error( 22 `XRPC resolve failed for ${procedure} (did=${did}): ${(e as Error).message}` 23 ); 24 } 25 26 const headers: Record<string, string> = { 27 "Content-Type": "application/json", 28 }; 29 30 // Pass service JWT for personalized components 31 if (serviceJwt) { 32 headers["Authorization"] = `Bearer ${serviceJwt}`; 33 } 34 35 let res: Response; 36 try { 37 res = await fetch(url, { 38 method: "POST", 39 headers, 40 body: JSON.stringify(input), 41 }); 42 } catch (e) { 43 throw new Error( 44 `XRPC fetch failed for ${procedure} (${url}): ${(e as Error).message}` 45 ); 46 } 47 48 return handleResponse(res, procedure); 49} 50 51/** 52 * Call an XRPC query endpoint (GET). 53 */ 54export async function callQuery( 55 did: string, 56 nsid: string, 57 params?: Record<string, string> 58): Promise<unknown> { 59 const serviceUrl = await resolveDidToService(did, "#inlay"); 60 const qs = new URLSearchParams(); 61 if (params) { 62 for (const [k, v] of Object.entries(params)) { 63 if (v != null) qs.set(k, v); 64 } 65 } 66 const qsStr = qs.toString(); 67 const url = `${serviceUrl}/xrpc/${nsid}${qsStr ? `?${qsStr}` : ""}`; 68 const res = await fetch(url); 69 return handleResponse(res, nsid); 70} 71 72async function handleResponse(res: Response, label: string): Promise<any> { 73 if (!res.ok) { 74 const text = await res.text().catch(() => ""); 75 MissingError.rethrowFromResponse(text); 76 let detail = text; 77 try { 78 const json = JSON.parse(text); 79 const err = json.error ?? json; 80 detail = err.message ?? err.name ?? text; 81 } catch {} 82 throw new Error(`XRPC ${label} failed (${res.status}): ${detail}`); 83 } 84 return res.json(); 85}