Canvas Studio now uses dockable floating panels, app settings/help navigation, and improved SVG export; the backend adds an SVG line-spacing analysis API with SciPy acceleration and new design templates.
34 lines
1.0 KiB
TypeScript
34 lines
1.0 KiB
TypeScript
const rawApiBase = (import.meta.env.VITE_API_BASE ?? '').trim();
|
|
|
|
export const API_BASE = rawApiBase.replace(/\/+$/, '');
|
|
|
|
export function apiUrl(path: string) {
|
|
if (!path) return API_BASE || '';
|
|
if (/^https?:\/\//i.test(path) || path.startsWith('data:') || path.startsWith('blob:')) {
|
|
return path;
|
|
}
|
|
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
return `${API_BASE}${normalizedPath}`;
|
|
}
|
|
|
|
export function apiEventSource(path: string) {
|
|
return new EventSource(apiUrl(path));
|
|
}
|
|
|
|
export async function readApiError(res: Response) {
|
|
const text = await res.text().catch(() => '');
|
|
if (!text) return `${res.status} ${res.statusText}`.trim();
|
|
try {
|
|
const parsed = JSON.parse(text);
|
|
return parsed.detail || parsed.message || text;
|
|
} catch {
|
|
return text;
|
|
}
|
|
}
|
|
|
|
export async function ensureOk(res: Response, fallback: string) {
|
|
if (res.ok) return res;
|
|
const detail = await readApiError(res);
|
|
throw new Error(`${fallback} (${res.status})${detail ? `: ${detail}` : ''}`);
|
|
}
|