All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
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>
90 lines
1.9 KiB
TypeScript
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" });
|
|
}
|