This repository has no description
1import { ClientResponseError, isXRPCErrorPayload, type XRPCErrorPayload } from "@atcute/client";
2import type { BobbinContext, QueryValue, XrpcRequestInit } from "./client";
3
4export const buildUrl = (
5 origin: string,
6 nsid: string,
7 params?: Record<string, QueryValue>
8): URL => {
9 const url = new URL(`/xrpc/${nsid}`, `${origin}/`);
10 if (params) {
11 for (const [key, value] of Object.entries(params)) {
12 if (value === undefined) continue;
13 if (Array.isArray(value)) {
14 for (const item of value) url.searchParams.append(key, String(item));
15 } else {
16 url.searchParams.set(key, String(value));
17 }
18 }
19 }
20 return url;
21};
22
23export const toResponseError = async (response: Response): Promise<ClientResponseError> => {
24 let data: XRPCErrorPayload = { error: "XRPCError", message: response.statusText };
25 try {
26 const body: unknown = await response.json();
27 if (isXRPCErrorPayload(body)) data = body;
28 } catch {
29 // keeps the status-line fallback for non-json bodies
30 }
31 return new ClientResponseError({ status: response.status, headers: response.headers, data });
32};
33
34export const jsonGet = async <T>(
35 ctx: BobbinContext,
36 nsid: string,
37 params?: Record<string, QueryValue>,
38 init?: XrpcRequestInit
39): Promise<T> => {
40 const response = await ctx.fetch(buildUrl(ctx.serviceUrl, nsid, params), {
41 headers: { accept: "application/json", ...init?.headers },
42 signal: init?.signal
43 });
44 if (!response.ok) throw await toResponseError(response);
45 return (await response.json()) as T;
46};
47
48export const jsonPost = async <T>(
49 ctx: BobbinContext,
50 nsid: string,
51 body: unknown,
52 init?: XrpcRequestInit
53): Promise<T> => {
54 const response = await ctx.fetch(buildUrl(ctx.serviceUrl, nsid), {
55 method: "POST",
56 headers: { "content-type": "application/json", accept: "application/json", ...init?.headers },
57 body: JSON.stringify(body),
58 signal: init?.signal
59 });
60 if (!response.ok) throw await toResponseError(response);
61 return (await response.json()) as T;
62};
63
64export const rawGet = async (
65 ctx: BobbinContext,
66 nsid: string,
67 params?: Record<string, QueryValue>,
68 init?: XrpcRequestInit
69): Promise<Response> => {
70 const response = await ctx.fetch(buildUrl(ctx.serviceUrl, nsid, params), {
71 headers: init?.headers,
72 signal: init?.signal
73 });
74 if (!response.ok) throw await toResponseError(response);
75 return response;
76};