Files
stack/apps/web/src/lib/api/client.ts
Jason Woltje f0704db560
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
fix: Resolve web package lint and typecheck errors
Fixes ESLint and TypeScript errors in web package to pass CI checks:

- Fixed all Quality Rails violations (14 explicit any types)
- Fixed deprecated React event types (FormEvent → SyntheticEvent)
- Fixed 26 TypeScript errors (Promise types, test mocks, HTMLElement assertions)
- Added vitest DOM matcher type definitions
- Fixed unused variables and empty functions
- Resolved 43+ additional lint errors

Typecheck:  0 errors
Lint: 542 remaining (non-blocking in CI)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-30 21:34:12 -06:00

90 lines
1.9 KiB
TypeScript

/**
* API Client for Mosaic Stack
* Handles authenticated requests to the backend API
*/
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3001";
export interface ApiError {
code: string;
message: string;
details?: unknown;
}
export interface ApiResponse<T> {
data: T;
meta?: {
total?: number;
page?: number;
limit?: number;
};
}
/**
* Make an authenticated API request
*/
export async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
const url = `${API_BASE_URL}${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
"Content-Type": "application/json",
...(options.headers ?? {}),
},
credentials: "include", // Include cookies for session
});
if (!response.ok) {
const error: ApiError = await response.json().catch(
(): ApiError => ({
code: "UNKNOWN_ERROR",
message: response.statusText || "An unknown error occurred",
})
);
throw new Error(error.message);
}
return response.json() as Promise<T>;
}
/**
* GET request helper
*/
export async function apiGet<T>(endpoint: string): Promise<T> {
return apiRequest<T>(endpoint, { method: "GET" });
}
/**
* POST request helper
*/
export async function apiPost<T>(endpoint: string, data?: unknown): Promise<T> {
const options: RequestInit = {
method: "POST",
};
if (data !== undefined) {
options.body = JSON.stringify(data);
}
return apiRequest<T>(endpoint, options);
}
/**
* PATCH request helper
*/
export async function apiPatch<T>(endpoint: string, data: unknown): Promise<T> {
return apiRequest<T>(endpoint, {
method: "PATCH",
body: JSON.stringify(data),
});
}
/**
* DELETE request helper
*/
export async function apiDelete<T>(endpoint: string): Promise<T> {
return apiRequest<T>(endpoint, { method: "DELETE" });
}