// Query strings and list answers shared by the API modules. /** "?a=1&b=x" from the defined, non-empty values. Empty when nothing is set. */ export function qs(params: Record): string { const sp = new URLSearchParams(); for (const [k, v] of Object.entries(params)) { if (v === undefined || v === null || v === "") continue; sp.set(k, String(v)); } const s = sp.toString(); return s ? `?${s}` : ""; } /** A list answer may come bare or wrapped as {key: [...]}. Both give the array. */ export function asList(raw: unknown, key: string): T[] { if (Array.isArray(raw)) return raw as T[]; if (raw && typeof raw === "object" && Array.isArray((raw as Record)[key])) { return (raw as Record)[key] as T[]; } return []; } /** The If-Match header for a version check. */ export function ifMatch(version: number): Record { return { "If-Match": String(version) }; }