From 0edf8c41911afc4f9fed150d40bf08b064efdb3d Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Tue, 9 Sep 2025 03:18:04 -0700 Subject: [PATCH] Added WIP structure for API library --- src/lib/api.ts | 11 ++++++++ src/lib/api/core.ts | 41 +++++++++++++++++++++++++++++ src/lib/api/index.ts | 0 src/lib/api/resources/characters.ts | 0 src/lib/api/resources/parties.ts | 0 src/lib/api/resources/summons.ts | 0 src/lib/api/resources/users.ts | 21 +++++++++++++++ src/lib/api/resources/weapons.ts | 2 ++ 8 files changed, 75 insertions(+) create mode 100644 src/lib/api.ts create mode 100644 src/lib/api/core.ts create mode 100644 src/lib/api/index.ts create mode 100644 src/lib/api/resources/characters.ts create mode 100644 src/lib/api/resources/parties.ts create mode 100644 src/lib/api/resources/summons.ts create mode 100644 src/lib/api/resources/users.ts create mode 100644 src/lib/api/resources/weapons.ts diff --git a/src/lib/api.ts b/src/lib/api.ts new file mode 100644 index 00000000..b92954d7 --- /dev/null +++ b/src/lib/api.ts @@ -0,0 +1,11 @@ +import { PUBLIC_API_BASE } from '$env/static/public' + +export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise + +export async function getJson(path: string, fetchFn: FetchLike, init?: RequestInit): Promise { + 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 +} diff --git a/src/lib/api/core.ts b/src/lib/api/core.ts new file mode 100644 index 00000000..6f57c0da --- /dev/null +++ b/src/lib/api/core.ts @@ -0,0 +1,41 @@ +import { PUBLIC_SIERO_API_URL } from '$env/static/public' + +export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise +export type Dict = Record + +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(fetchFn: FetchLike, url: string, init?: RequestInit): Promise { + 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 +} + +export const get = (f: FetchLike, path: string, params?: Dict, init?: RequestInit) => + json(f, buildUrl(path, params), init) + +export const post = (f: FetchLike, path: string, body?: unknown, init?: RequestInit) => + json(f, path, { method: 'POST', body: body ? JSON.stringify(body) : undefined, ...init }) + +export const put = (f: FetchLike, path: string, body?: unknown, init?: RequestInit) => + json(f, path, { method: 'PUT', body: body ? JSON.stringify(body) : undefined, ...init }) + +export const del = (f: FetchLike, path: string, init?: RequestInit) => + json(f, path, { method: 'DELETE', ...init }) diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/api/resources/characters.ts b/src/lib/api/resources/characters.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/api/resources/parties.ts b/src/lib/api/resources/parties.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/api/resources/summons.ts b/src/lib/api/resources/summons.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/api/resources/users.ts b/src/lib/api/resources/users.ts new file mode 100644 index 00000000..39cb7e2a --- /dev/null +++ b/src/lib/api/resources/users.ts @@ -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(f, `/users/info/${encodeURIComponent(username)}`, undefined, init) +} diff --git a/src/lib/api/resources/weapons.ts b/src/lib/api/resources/weapons.ts new file mode 100644 index 00000000..040d44b2 --- /dev/null +++ b/src/lib/api/resources/weapons.ts @@ -0,0 +1,2 @@ +import type { FetchLike, Dict } from '../core' +import { get, post, put, del } from '../core'