export type BytesParseOptions = { defaultUnit?: "b" | "kb" | "mb" | "gb" | "tb"; }; const UNIT_MULTIPLIERS: Record = { b: 1, kb: 1024, k: 1024, mb: 1024 ** 2, m: 1024 ** 2, gb: 1024 ** 3, g: 1024 ** 3, tb: 1024 ** 4, t: 1024 ** 4, }; export function parseByteSize(raw: string, opts?: BytesParseOptions): number { const trimmed = String(raw ?? "") .trim() .toLowerCase(); if (!trimmed) { throw new Error("invalid byte size (empty)"); } const m = /^(\d+(?:\.\d+)?)([a-z]+)?$/.exec(trimmed); if (!m) { throw new Error(`invalid byte size: ${raw}`); } const value = Number(m[1]); if (!Number.isFinite(value) || value < 0) { throw new Error(`invalid byte size: ${raw}`); } const unit = (m[2] ?? opts?.defaultUnit ?? "b").toLowerCase(); const multiplier = UNIT_MULTIPLIERS[unit]; if (!multiplier) { throw new Error(`invalid byte size unit: ${raw}`); } const bytes = Math.round(value * multiplier); if (!Number.isFinite(bytes)) { throw new Error(`invalid byte size: ${raw}`); } return bytes; }