53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
export type QueryParamValue = string | number | string[] | undefined;
|
|
|
|
function joinUrl(baseUrl: string, path: string): string {
|
|
const base = baseUrl.replace(/\/$/, '');
|
|
const endpoint = path.startsWith('/') ? path : `/${path}`;
|
|
return `${base}${endpoint}`;
|
|
}
|
|
|
|
function appendQueryParams(url: string, params?: Record<string, QueryParamValue>): string {
|
|
const searchParams = new URLSearchParams();
|
|
|
|
Object.entries(params ?? {}).forEach(([key, value]) => {
|
|
if (Array.isArray(value)) {
|
|
value.forEach((item) => searchParams.append(key, item));
|
|
return;
|
|
}
|
|
|
|
if (value !== undefined && value !== '') {
|
|
searchParams.set(key, String(value));
|
|
}
|
|
});
|
|
|
|
const query = searchParams.toString();
|
|
return query ? `${url}?${query}` : url;
|
|
}
|
|
|
|
/** Собирает URL API из base, пути и query-параметров. */
|
|
export function buildApiUrl(
|
|
baseUrl: string,
|
|
path: string,
|
|
params?: Record<string, QueryParamValue>,
|
|
): string {
|
|
return appendQueryParams(joinUrl(baseUrl, path), params);
|
|
}
|
|
|
|
/** Выполняет GET-запрос и добавляет query-параметры в едином формате для всех API. */
|
|
export async function getJson<T>(
|
|
baseUrl: string,
|
|
path: string,
|
|
params?: Record<string, QueryParamValue>,
|
|
init?: RequestInit,
|
|
): Promise<T> {
|
|
const url = buildApiUrl(baseUrl, path, params);
|
|
|
|
const response = await fetch(url, init);
|
|
if (!response.ok) {
|
|
const message = await response.text();
|
|
throw new Error(message || `${response.status} ${response.statusText}`);
|
|
}
|
|
|
|
return response.json() as Promise<T>;
|
|
}
|