aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/ui-new/src/lib/tsrs-utils.ts
blob: f48f851833113ca8577de6fdeb9f1e18cdd6ba22 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
export type Maybe<T> = T | null | undefined;

export function toNumber(
  value: Maybe<number | bigint | string>,
  fallback = 0,
): number {
  if (value === null || value === undefined) return fallback;

  if (typeof value === "number") {
    if (Number.isFinite(value)) return value;
    return fallback;
  }

  if (typeof value === "bigint") {
    // safe conversion for typical values (timestamps, sizes). Might overflow for huge bigint.
    return Number(value);
  }

  if (typeof value === "string") {
    const n = Number(value);
    return Number.isFinite(n) ? n : fallback;
  }

  return fallback;
}

/**
 * Like `toNumber` but ensures non-negative result (clamps at 0).
 */
export function toNonNegativeNumber(
  value: Maybe<number | bigint | string>,
  fallback = 0,
): number {
  const n = toNumber(value, fallback);
  return n < 0 ? 0 : n;
}

export function toDate(
  value: Maybe<number | bigint | string>,
  opts?: { isSeconds?: boolean },
): Date | null {
  if (value === null || value === undefined) return null;

  const isSeconds = opts?.isSeconds ?? true;

  // accept bigint, number, numeric string
  const n = toNumber(value, NaN);
  if (Number.isNaN(n)) return null;

  const ms = isSeconds ? Math.floor(n) * 1000 : Math.floor(n);
  return new Date(ms);
}

/**
 * Convert a binding boolean-ish value (0/1, "true"/"false", boolean) to boolean.
 */
export function toBoolean(value: unknown, fallback = false): boolean {
  if (value === null || value === undefined) return fallback;
  if (typeof value === "boolean") return value;
  if (typeof value === "number") return value !== 0;
  if (typeof value === "string") {
    const s = value.toLowerCase().trim();
    if (s === "true" || s === "1") return true;
    if (s === "false" || s === "0") return false;
  }
  return fallback;
}