1import type {
2 CanonicalResourceUri,
3 Did,
4 ParsedCanonicalResourceUri,
5 ParsedResourceUri,
6 ResourceUri
7} from '@atcute/lexicons';
8import type { Backlink, BacklinksSource } from './at/constellation';
9import { parse as parseTid } from '@atcute/tid';
10
11export const toResourceUri = (parsed: ParsedResourceUri): ResourceUri => {
12 return `at://${parsed.repo}${parsed.collection ? `/${parsed.collection}${parsed.rkey ? `/${parsed.rkey}` : ''}` : ''}`;
13};
14export const toCanonicalUri = (
15 parsed: ParsedCanonicalResourceUri | Backlink
16): CanonicalResourceUri => {
17 if ('did' in parsed) return `at://${parsed.did}/${parsed.collection}/${parsed.rkey}`;
18 return `at://${parsed.repo}/${parsed.collection}/${parsed.rkey}${parsed.fragment ? `#${parsed.fragment}` : ''}`;
19};
20
21export const extractDidFromUri = (uri: string): Did | null => {
22 if (!uri.startsWith('at://')) return null;
23 const idx = uri.indexOf('/', 5);
24 if (idx === -1) return uri.slice(5) as Did;
25 return uri.slice(5, idx) as Did;
26};
27
28export const likeSource: BacklinksSource = 'app.bsky.feed.like:subject.uri';
29export const repostSource: BacklinksSource = 'app.bsky.feed.repost:subject.uri';
30export const replySource: BacklinksSource = 'app.bsky.feed.post:reply.parent.uri';
31export const replyRootSource: BacklinksSource = 'app.bsky.feed.post:reply.root.uri';
32export const blockSource: BacklinksSource = 'app.bsky.graph.block:subject';
33
34export const timestampFromCursor = (cursor: string | undefined) => {
35 if (!cursor) return undefined;
36 try {
37 return parseTid(cursor).timestamp;
38 } catch {
39 return undefined;
40 }
41};