frontend client for gemstone. decentralised workplace app
2
fork

Configure Feed

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

feat: get full commit helper

serenity 3c9346a7 84f0b4d8

+67 -1
+67 -1
src/lib/utils/atproto/index.ts
··· 9 9 atUriAuthoritySchema, 10 10 nsidSchema, 11 11 } from "@/lib/types/atproto"; 12 - import { comAtprotoRepoGetRecordResponseSchema } from "@/lib/types/lexicon/com.atproto.repo.getRecord"; 12 + import type { 13 + ComAtprotoRepoGetRecordResponse} from "@/lib/types/lexicon/com.atproto.repo.getRecord"; 14 + import { 15 + comAtprotoRepoGetRecordResponseSchema, 16 + } from "@/lib/types/lexicon/com.atproto.repo.getRecord"; 13 17 import type { Result } from "@/lib/utils/result"; 14 18 import type { DidDocumentResolver } from "@atcute/identity-resolver"; 15 19 import { ··· 82 86 return { ok: false, error: responseParseError }; 83 87 } 84 88 return { ok: true, data: record.value }; 89 + }; 90 + 91 + export const getCommitFromFullAtUri = async ({ 92 + authority, 93 + collection, 94 + rKey, 95 + }: AtUri): Promise<Result<ComAtprotoRepoGetRecordResponse, unknown>> => { 96 + const didDocResult = await resolveDidDoc(authority); 97 + if (!didDocResult.ok) return { ok: false, error: didDocResult.error }; 98 + 99 + if (!collection || !rKey) 100 + return { 101 + ok: false, 102 + error: "No rkey or collection found in provided AtUri object", 103 + }; 104 + 105 + const { service: services } = didDocResult.data; 106 + if (!services) 107 + return { 108 + ok: false, 109 + error: { message: "Resolved DID document has no service field." }, 110 + }; 111 + 112 + const pdsService = services.find( 113 + (service) => 114 + service.id === "#atproto_pds" && 115 + service.type === "AtprotoPersonalDataServer", 116 + ); 117 + 118 + if (!pdsService) 119 + return { 120 + ok: false, 121 + error: { 122 + message: 123 + "Resolved DID document has no PDS service listed in the document.", 124 + }, 125 + }; 126 + 127 + const pdsEndpointRecord = pdsService.serviceEndpoint; 128 + let pdsEndpointUrl; 129 + try { 130 + // @ts-expect-error yes, we are coercing something that is explicitly not a string into a string, but in this case we want to be specific. only serviceEndpoints with valid atproto pds URLs should be allowed. 131 + pdsEndpointUrl = new URL(pdsEndpointRecord).origin; 132 + } catch (err) { 133 + return { ok: false, error: err }; 134 + } 135 + const req = new Request( 136 + `${pdsEndpointUrl}/xrpc/com.atproto.repo.getRecord?repo=${didDocResult.data.id}&collection=${collection}&rkey=${rKey}`, 137 + ); 138 + 139 + const res = await fetch(req); 140 + const data: unknown = await res.json(); 141 + 142 + const { 143 + success: responseParseSuccess, 144 + error: responseParseError, 145 + data: record, 146 + } = comAtprotoRepoGetRecordResponseSchema.safeParse(data); 147 + if (!responseParseSuccess) { 148 + return { ok: false, error: responseParseError }; 149 + } 150 + return { ok: true, data: record }; 85 151 }; 86 152 87 153 export const didDocResolver: DidDocumentResolver =