65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
/** Response interface for all API calls */
|
|
export interface ApiResponse<T = any> {
|
|
success: boolean;
|
|
error: string;
|
|
data: T;
|
|
}
|
|
|
|
/**
|
|
* Generic API wrapper that performs a POST request with URL-encoded form data.
|
|
* Returns the `data` field on success, or `undefined` on failure.
|
|
*
|
|
* @param url - The API endpoint URL
|
|
* @param data - Key-value pairs to send as form data
|
|
* @returns The response data on success, or `undefined` on failure
|
|
*/
|
|
export async function apiWrapper<T>(url: string, data: Record<string, any>): Promise<T | undefined> {
|
|
try {
|
|
const params = new URLSearchParams();
|
|
Object.entries(data).forEach(([key, value]) => {
|
|
params.append(key, String(value));
|
|
});
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
mode: "cors",
|
|
cache: "no-cache",
|
|
credentials: "same-origin",
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
redirect: "follow",
|
|
referrerPolicy: "no-referrer",
|
|
body: params.toString(),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error(`HTTP failed: ${response.status}`);
|
|
}
|
|
|
|
const payload = await response.json() as ApiResponse<T>;
|
|
|
|
if (payload.success) {
|
|
return payload.data;
|
|
} else {
|
|
console.error(`API failed: ${payload.error}`);
|
|
return undefined;
|
|
}
|
|
} catch (error) {
|
|
console.error(`Fetch failed: ${error}`);
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Boolean API wrapper. Calls {@link apiWrapper} and returns `true` if the
|
|
* response is not `undefined`, otherwise `false`.
|
|
*
|
|
* @param url - The API endpoint URL
|
|
* @param data - Key-value pairs to send as form data
|
|
* @returns `true` on success, `false` on failure
|
|
*/
|
|
export async function boolApiWrapper(url: string, data: Record<string, any>): Promise<boolean> {
|
|
const rv = await apiWrapper<null>(url, data);
|
|
return rv !== undefined;
|
|
}
|