this repo has no description
1const API_BASE = '/xrpc' 2export class ApiError extends Error { 3 public did?: string 4 constructor(public status: number, public error: string, message: string, did?: string) { 5 super(message) 6 this.name = 'ApiError' 7 this.did = did 8 } 9} 10async function xrpc<T>(method: string, options?: { 11 method?: 'GET' | 'POST' 12 params?: Record<string, string> 13 body?: unknown 14 token?: string 15}): Promise<T> { 16 const { method: httpMethod = 'GET', params, body, token } = options ?? {} 17 let url = `${API_BASE}/${method}` 18 if (params) { 19 const searchParams = new URLSearchParams(params) 20 url += `?${searchParams}` 21 } 22 const headers: Record<string, string> = {} 23 if (token) { 24 headers['Authorization'] = `Bearer ${token}` 25 } 26 if (body) { 27 headers['Content-Type'] = 'application/json' 28 } 29 const res = await fetch(url, { 30 method: httpMethod, 31 headers, 32 body: body ? JSON.stringify(body) : undefined, 33 }) 34 if (!res.ok) { 35 const err = await res.json().catch(() => ({ error: 'Unknown', message: res.statusText })) 36 throw new ApiError(res.status, err.error, err.message, err.did) 37 } 38 return res.json() 39} 40export interface Session { 41 did: string 42 handle: string 43 email?: string 44 emailConfirmed?: boolean 45 preferredChannel?: string 46 preferredChannelVerified?: boolean 47 accessJwt: string 48 refreshJwt: string 49} 50export interface AppPassword { 51 name: string 52 createdAt: string 53} 54export interface InviteCode { 55 code: string 56 available: number 57 disabled: boolean 58 forAccount: string 59 createdBy: string 60 createdAt: string 61 uses: { usedBy: string; usedAt: string }[] 62} 63export type VerificationChannel = 'email' | 'discord' | 'telegram' | 'signal' 64export interface CreateAccountParams { 65 handle: string 66 email: string 67 password: string 68 inviteCode?: string 69 verificationChannel?: VerificationChannel 70 discordId?: string 71 telegramUsername?: string 72 signalNumber?: string 73} 74export interface CreateAccountResult { 75 handle: string 76 did: string 77 verificationRequired: boolean 78 verificationChannel: string 79} 80export interface ConfirmSignupResult { 81 accessJwt: string 82 refreshJwt: string 83 handle: string 84 did: string 85 email?: string 86 emailConfirmed?: boolean 87 preferredChannel?: string 88 preferredChannelVerified?: boolean 89} 90export const api = { 91 async createAccount(params: CreateAccountParams): Promise<CreateAccountResult> { 92 return xrpc('com.atproto.server.createAccount', { 93 method: 'POST', 94 body: { 95 handle: params.handle, 96 email: params.email, 97 password: params.password, 98 inviteCode: params.inviteCode, 99 verificationChannel: params.verificationChannel, 100 discordId: params.discordId, 101 telegramUsername: params.telegramUsername, 102 signalNumber: params.signalNumber, 103 }, 104 }) 105 }, 106 async confirmSignup(did: string, verificationCode: string): Promise<ConfirmSignupResult> { 107 return xrpc('com.atproto.server.confirmSignup', { 108 method: 'POST', 109 body: { did, verificationCode }, 110 }) 111 }, 112 async resendVerification(did: string): Promise<{ success: boolean }> { 113 return xrpc('com.atproto.server.resendVerification', { 114 method: 'POST', 115 body: { did }, 116 }) 117 }, 118 async createSession(identifier: string, password: string): Promise<Session> { 119 return xrpc('com.atproto.server.createSession', { 120 method: 'POST', 121 body: { identifier, password }, 122 }) 123 }, 124 async getSession(token: string): Promise<Session> { 125 return xrpc('com.atproto.server.getSession', { token }) 126 }, 127 async refreshSession(refreshJwt: string): Promise<Session> { 128 return xrpc('com.atproto.server.refreshSession', { 129 method: 'POST', 130 token: refreshJwt, 131 }) 132 }, 133 async deleteSession(token: string): Promise<void> { 134 await xrpc('com.atproto.server.deleteSession', { 135 method: 'POST', 136 token, 137 }) 138 }, 139 async listAppPasswords(token: string): Promise<{ passwords: AppPassword[] }> { 140 return xrpc('com.atproto.server.listAppPasswords', { token }) 141 }, 142 async createAppPassword(token: string, name: string): Promise<{ name: string; password: string; createdAt: string }> { 143 return xrpc('com.atproto.server.createAppPassword', { 144 method: 'POST', 145 token, 146 body: { name }, 147 }) 148 }, 149 async revokeAppPassword(token: string, name: string): Promise<void> { 150 await xrpc('com.atproto.server.revokeAppPassword', { 151 method: 'POST', 152 token, 153 body: { name }, 154 }) 155 }, 156 async getAccountInviteCodes(token: string): Promise<{ codes: InviteCode[] }> { 157 return xrpc('com.atproto.server.getAccountInviteCodes', { token }) 158 }, 159 async createInviteCode(token: string, useCount: number = 1): Promise<{ code: string }> { 160 return xrpc('com.atproto.server.createInviteCode', { 161 method: 'POST', 162 token, 163 body: { useCount }, 164 }) 165 }, 166 async requestPasswordReset(email: string): Promise<void> { 167 await xrpc('com.atproto.server.requestPasswordReset', { 168 method: 'POST', 169 body: { email }, 170 }) 171 }, 172 async resetPassword(token: string, password: string): Promise<void> { 173 await xrpc('com.atproto.server.resetPassword', { 174 method: 'POST', 175 body: { token, password }, 176 }) 177 }, 178 async requestEmailUpdate(token: string): Promise<{ tokenRequired: boolean }> { 179 return xrpc('com.atproto.server.requestEmailUpdate', { 180 method: 'POST', 181 token, 182 }) 183 }, 184 async updateEmail(token: string, email: string, emailToken?: string): Promise<void> { 185 await xrpc('com.atproto.server.updateEmail', { 186 method: 'POST', 187 token, 188 body: { email, token: emailToken }, 189 }) 190 }, 191 async updateHandle(token: string, handle: string): Promise<void> { 192 await xrpc('com.atproto.identity.updateHandle', { 193 method: 'POST', 194 token, 195 body: { handle }, 196 }) 197 }, 198 async requestAccountDelete(token: string): Promise<void> { 199 await xrpc('com.atproto.server.requestAccountDelete', { 200 method: 'POST', 201 token, 202 }) 203 }, 204 async deleteAccount(did: string, password: string, deleteToken: string): Promise<void> { 205 await xrpc('com.atproto.server.deleteAccount', { 206 method: 'POST', 207 body: { did, password, token: deleteToken }, 208 }) 209 }, 210 async describeServer(): Promise<{ 211 availableUserDomains: string[] 212 inviteCodeRequired: boolean 213 links?: { privacyPolicy?: string; termsOfService?: string } 214 }> { 215 return xrpc('com.atproto.server.describeServer') 216 }, 217 async getNotificationPrefs(token: string): Promise<{ 218 preferredChannel: string 219 email: string 220 discordId: string | null 221 discordVerified: boolean 222 telegramUsername: string | null 223 telegramVerified: boolean 224 signalNumber: string | null 225 signalVerified: boolean 226 }> { 227 return xrpc('com.bspds.account.getNotificationPrefs', { token }) 228 }, 229 async updateNotificationPrefs(token: string, prefs: { 230 preferredChannel?: string 231 discordId?: string 232 telegramUsername?: string 233 signalNumber?: string 234 }): Promise<{ success: boolean }> { 235 return xrpc('com.bspds.account.updateNotificationPrefs', { 236 method: 'POST', 237 token, 238 body: prefs, 239 }) 240 }, 241 async describeRepo(token: string, repo: string): Promise<{ 242 handle: string 243 did: string 244 didDoc: unknown 245 collections: string[] 246 handleIsCorrect: boolean 247 }> { 248 return xrpc('com.atproto.repo.describeRepo', { 249 token, 250 params: { repo }, 251 }) 252 }, 253 async listRecords(token: string, repo: string, collection: string, options?: { 254 limit?: number 255 cursor?: string 256 reverse?: boolean 257 }): Promise<{ 258 records: Array<{ uri: string; cid: string; value: unknown }> 259 cursor?: string 260 }> { 261 const params: Record<string, string> = { repo, collection } 262 if (options?.limit) params.limit = String(options.limit) 263 if (options?.cursor) params.cursor = options.cursor 264 if (options?.reverse) params.reverse = 'true' 265 return xrpc('com.atproto.repo.listRecords', { token, params }) 266 }, 267 async getRecord(token: string, repo: string, collection: string, rkey: string): Promise<{ 268 uri: string 269 cid: string 270 value: unknown 271 }> { 272 return xrpc('com.atproto.repo.getRecord', { 273 token, 274 params: { repo, collection, rkey }, 275 }) 276 }, 277 async createRecord(token: string, repo: string, collection: string, record: unknown, rkey?: string): Promise<{ 278 uri: string 279 cid: string 280 }> { 281 return xrpc('com.atproto.repo.createRecord', { 282 method: 'POST', 283 token, 284 body: { repo, collection, record, rkey }, 285 }) 286 }, 287 async putRecord(token: string, repo: string, collection: string, rkey: string, record: unknown): Promise<{ 288 uri: string 289 cid: string 290 }> { 291 return xrpc('com.atproto.repo.putRecord', { 292 method: 'POST', 293 token, 294 body: { repo, collection, rkey, record }, 295 }) 296 }, 297 async deleteRecord(token: string, repo: string, collection: string, rkey: string): Promise<void> { 298 await xrpc('com.atproto.repo.deleteRecord', { 299 method: 'POST', 300 token, 301 body: { repo, collection, rkey }, 302 }) 303 }, 304}