Snippet

public

Language: typescript

Created
Jan 22, 2026 • 11:23 AM
Visibility
public
Raw
1// Lightweight fetch wrapper with typed responses
2
3export type ApiError = {
4  status: number
5  message: string
6}
7
8export class ApiClient {
9  private baseUrl: string
10  private token?: string
11
12  constructor(baseUrl: string, token?: string) {
13    this.baseUrl = baseUrl.replace(/\/$/, "")
14    this.token = token
15  }
16
17  setToken(token: string) {
18    this.token = token
19  }
20
21  async get<T>(path: string): Promise<T> {
22    return this.request<T>("GET", path)
23  }
24
25  async post<T>(path: string, body?: unknown): Promise<T> {
26    return this.request<T>("POST", path, body)
27  }
28
29  private async request<T>(
30    method: string,
31    path: string,
32    body?: unknown
33  ): Promise<T> {
34    const res = await fetch(this.baseUrl + path, {
35      method,
36      headers: {
37        "Content-Type": "application/json",
38        ...(this.token && { Authorization: `Bearer ${this.token}` }),
39      },
40      body: body ? JSON.stringify(body) : undefined,
41    })
42
43    if (!res.ok) {
44      const msg = await res.text()
45      throw <ApiError>{
46        status: res.status,
47        message: msg || res.statusText,
48      }
49    }
50
51    return (await res.json()) as T
52  }
53}
54
55// Example usage:
56const api = new ApiClient("https://api.pastehub.de", "user-token")
57
58api.get<{ username: string }>("/me").then((me) => {
59  console.log("Logged in as", me.username)
60})
61