SPB Git forge

spb/countryatlas

Public
20commits 1branches 0releases
268.3 MBsize
maindefault branch
12 days agolast push
TypeScript 57% Python 38.6% JavaScript 3.6% CSS 0.6%
1.4 KB · 38 lines typescript
Raw Blame History
1/**2 * Server-safe URL parameter helpers (no 'use client' directive) shared by server components (searchParams3 * parsing) and the client `useUrlState` hook in ./url-state.ts, which re-exports them.4 */5export type UrlPatch = Record<string, string | number | boolean | null | undefined>;67export function applyPatch(current: URLSearchParams, patch: UrlPatch): URLSearchParams {8  const p = new URLSearchParams(current.toString());9  for (const [k, v] of Object.entries(patch)) {10    if (v === undefined || v === null || v === '' || v === false) p.delete(k);11    else p.set(k, v === true ? '1' : String(v));12  }13  return p;14}1516/** Parse "a,b,c" → ["a","b","c"] limited to slug-safe tokens. */17export function parseList(v: string | null | undefined, max = 8): string[] {18  if (!v) return [];19  const out: string[] = [];20  for (const part of v.split(',')) {21    const s = part.trim().toLowerCase();22    if (s && /^[a-z0-9][a-z0-9-]*$/.test(s) && !out.includes(s)) out.push(s);23    if (out.length >= max) break;24  }25  return out;26}2728export function parseYear(v: string | null | undefined): number | null {29  if (!v) return null;30  const n = Number(v);31  return Number.isInteger(n) && n >= 1750 && n <= 2100 ? n : null;32}3334/** First string value of a Next `searchParams` entry. */35export function firstParam(v: string | string[] | undefined): string | null {36  return Array.isArray(v) ? (v[0] ?? null) : (v ?? null);37}38