an app to share curated trails sidetrail.app
atproto nextjs react rsc
50
fork

Configure Feed

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

resolve at:// before publish

+22 -2
+22 -2
data/actions.ts
··· 4 4 import { after } from "next/server"; 5 5 import { getLexClient } from "@/data/lex-client"; 6 6 import { generateTid } from "./tid"; 7 - import { loadCurrentUser } from "./queries"; 7 + import { loadCurrentUser, resolveHandleToDid } from "./queries"; 8 8 import { refresh } from "next/cache"; 9 9 import * as trail from "@/lib/lexicons/app/sidetrail/trail"; 10 10 import * as walk from "@/lib/lexicons/app/sidetrail/walk"; ··· 22 22 } from "@/data/db"; 23 23 import { eq, and } from "drizzle-orm"; 24 24 import { cidForLex } from "@atproto/lex-cbor"; 25 + import { AtUri } from "@atproto/syntax"; 25 26 26 27 // ============================================================================ 27 28 // Helpers ··· 30 31 function extractRkey(uri: string): string { 31 32 const parts = uri.split("/"); 32 33 return parts[parts.length - 1]; 34 + } 35 + 36 + /** 37 + * Resolves an at:// URI to use a DID instead of a handle. 38 + * If the URI already uses a DID or is not an at:// URI, returns it unchanged. 39 + */ 40 + async function resolveAtUri(uri: string): Promise<string> { 41 + if (!uri.startsWith("at://")) { 42 + return uri; 43 + } 44 + 45 + const parsed = new AtUri(uri); 46 + if (parsed.host.startsWith("did:")) { 47 + return uri; 48 + } 49 + 50 + const did = await resolveHandleToDid(parsed.host); 51 + return `at://${did}/${parsed.collection}/${parsed.rkey}`; 33 52 } 34 53 35 54 // ============================================================================ ··· 414 433 } 415 434 416 435 if (stop.external) { 436 + const resolvedUri = await resolveAtUri(stop.external.uri); 417 437 const external: trail.External = { 418 - uri: stop.external.uri as l.Uri, 438 + uri: resolvedUri as l.Uri, 419 439 }; 420 440 if (stop.external.title) { 421 441 external.title = stop.external.title;