Added WIP structure for API library

This commit is contained in:
Justin Edmund 2025-09-09 03:18:04 -07:00
parent 660cc8d028
commit 0edf8c4191
8 changed files with 75 additions and 0 deletions

11
src/lib/api.ts Normal file
View file

@ -0,0 +1,11 @@
import { PUBLIC_API_BASE } from '$env/static/public'
export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>
export async function getJson<T>(path: string, fetchFn: FetchLike, init?: RequestInit): Promise<T> {
const base = PUBLIC_API_BASE || ''
const url = path.startsWith('http') ? path : `${base}${path}`
const res = await fetchFn(url, { credentials: 'include', ...init })
if (!res.ok) throw new Error(`HTTP ${res.status} ${url}`)
return res.json() as Promise<T>
}

41
src/lib/api/core.ts Normal file
View file

@ -0,0 +1,41 @@
import { PUBLIC_SIERO_API_URL } from '$env/static/public'
export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>
export type Dict = Record<string, unknown>
const API = PUBLIC_SIERO_API_URL?.replace(/\/$/, '') ?? 'http://localhost:3000/api/v1'
export function buildUrl(path: string, params?: Dict) {
const url = new URL(path.startsWith('http') ? path : `${API}${path}`, API)
if (params) {
for (const [key, value] of Object.entries(params)) {
if (value === undefined || value === null) continue
if (Array.isArray(value)) value.forEach((x) => url.searchParams.append(key, String(x)))
else url.searchParams.set(key, String(value))
}
}
return url.toString()
}
export async function json<T>(fetchFn: FetchLike, url: string, init?: RequestInit): Promise<T> {
const res = await fetchFn(url, {
credentials: 'include',
headers: { 'Content-Type': 'application/json', ...(init?.headers || {}) },
...init
})
if (!res.ok) throw new Error(`HTTP ${res.status} ${url}`)
return res.json() as Promise<T>
}
export const get = <T>(f: FetchLike, path: string, params?: Dict, init?: RequestInit) =>
json<T>(f, buildUrl(path, params), init)
export const post = <T>(f: FetchLike, path: string, body?: unknown, init?: RequestInit) =>
json<T>(f, path, { method: 'POST', body: body ? JSON.stringify(body) : undefined, ...init })
export const put = <T>(f: FetchLike, path: string, body?: unknown, init?: RequestInit) =>
json<T>(f, path, { method: 'PUT', body: body ? JSON.stringify(body) : undefined, ...init })
export const del = <T>(f: FetchLike, path: string, init?: RequestInit) =>
json<T>(f, path, { method: 'DELETE', ...init })

0
src/lib/api/index.ts Normal file
View file

View file

View file

View file

View file

@ -0,0 +1,21 @@
import type { FetchLike } from '../core'
import { get } from '../core'
export interface UserInfoResponse {
id: string
username: string
language: string
private: boolean
gender: number
theme: string
role: number
avatar: {
picture: string
element: string
}
}
export const users = {
info: (f: FetchLike, username: string, init?: RequestInit) =>
get<UserInfoResponse>(f, `/users/info/${encodeURIComponent(username)}`, undefined, init)
}

View file

@ -0,0 +1,2 @@
import type { FetchLike, Dict } from '../core'
import { get, post, put, del } from '../core'