Highly ambitious ATProtocol AppView service and sdks
1/**
2 * Parsed AT-URI components
3 */
4export interface AtUri {
5 protocol: string;
6 did: string;
7 collection: string;
8 rkey: string;
9 fragment?: string;
10}
11
12/**
13 * Parse an AT-URI into its components
14 * Format: at://did:method:identifier/collection/rkey#fragment
15 */
16export function parseAtUri(uri: string): AtUri {
17 if (!uri.startsWith("at://")) {
18 throw new Error(`Invalid AT-URI: must start with at:// - got ${uri}`);
19 }
20
21 const withoutProtocol = uri.slice(5); // Remove 'at://'
22 const [didAndPath, fragment] = withoutProtocol.split("#");
23 const parts = didAndPath.split("/");
24
25 if (parts.length < 3) {
26 throw new Error(`Invalid AT-URI: missing required parts - got ${uri}`);
27 }
28
29 const [did, collection, rkey, ...rest] = parts;
30
31 if (rest.length > 0) {
32 throw new Error(`Invalid AT-URI: too many path segments - got ${uri}`);
33 }
34
35 return {
36 protocol: "at",
37 did,
38 collection,
39 rkey,
40 fragment,
41 };
42}
43
44/**
45 * Build an AT-URI from components
46 */
47export function buildAtUri(components: Omit<AtUri, "protocol">): string {
48 const { did, collection, rkey, fragment } = components;
49 let uri = `at://${did}/${collection}/${rkey}`;
50
51 if (fragment) {
52 uri += `#${fragment}`;
53 }
54
55 return uri;
56}
57
58/**
59 * Extract just the record key from an AT-URI
60 */
61export function getRkeyFromUri(uri: string): string {
62 return parseAtUri(uri).rkey;
63}
64
65/**
66 * Extract the DID from an AT-URI
67 */
68export function getDidFromUri(uri: string): string {
69 return parseAtUri(uri).did;
70}
71
72/**
73 * Extract the collection from an AT-URI
74 */
75export function getCollectionFromUri(uri: string): string {
76 return parseAtUri(uri).collection;
77}
78
79/**
80 * Build a slice URI from DID and slice ID
81 */
82export function buildSliceUri(did: string, sliceId: string): string {
83 return buildAtUri({ did, collection: "network.slices.slice", rkey: sliceId });
84}