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