SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
1.5 KB · 39 lines typescript
Raw Blame History
1/** URL state helpers for server-side filtered pages (§295). */2export type SP = Record<string, string | string[] | undefined>;34export function str(sp: SP, key: string, fallback = ''): string {5  const v = sp[key];6  const s = Array.isArray(v) ? v[0] : v;7  return (s ?? fallback).toString().trim();8}910export function int(sp: SP, key: string, fallback: number, min = -Infinity, max = Infinity): number {11  const n = Number.parseInt(str(sp, key, ''), 10);12  if (!Number.isFinite(n)) return fallback;13  return Math.min(max, Math.max(min, n));14}1516export function oneOf<T extends string>(sp: SP, key: string, allowed: readonly T[], fallback: T): T {17  const v = str(sp, key, '');18  return (allowed as readonly string[]).includes(v) ? (v as T) : fallback;19}2021export function bool(sp: SP, key: string): boolean | null {22  const v = str(sp, key, '');23  if (v === '1' || v === 'true' || v === 'yes') return true;24  if (v === '0' || v === 'false' || v === 'no') return false;25  return null;26}2728/** Build a query string from the current params with overrides (drops empty values). */29export function withParams(current: Record<string, string | number | null | undefined>, overrides: Record<string, string | number | null | undefined>): string {30  const merged = { ...current, ...overrides };31  const qs = new URLSearchParams();32  for (const [k, v] of Object.entries(merged)) {33    if (v == null || v === '' || v === 'all' && k !== 'level') continue;34    qs.set(k, String(v));35  }36  const s = qs.toString();37  return s ? `?${s}` : '';38}39