export type Track = {id:string;url:string;title:string;artist:string;explicit:boolean|null;credit?:string;pr?:number;added_at?:string;commit?:string}; export type PR = {num:number;title:string;author:string;status:string;created_at:string;url:string}; export type Detail = PR & {comments:{id:string;author:string;created_at:string;content:string}[];change:{action:'add'|'remove';track:Track;path:string}|null;problem:string|null;revision:string;mergeable:boolean}; export type Snapshot = {head:string;tracks:Track[];prs:PR[];history:{id:string;title:string;authors:string[];created_at:string;url:string}[];invalid_files:number}; export type User = {username:string;is_admin:boolean}; export type Config = {base_url:string;repo_url:string;event_url:string}; export async function api(url:string, options:RequestInit={}, csrf=''):Promise { const response=await fetch(url,{credentials:'same-origin',...options,headers:{'Content-Type':'application/json',...(csrf?{'X-CSRF-Token':csrf}:{}),...options.headers}}); const data=await response.json().catch(()=>{throw new Error('The Space is restarting or temporarily unavailable. Please try again shortly.');}); if(!response.ok) throw new Error(data.error?.message||'The request could not be completed. Please try again.'); return data; }