/ src / lib / runtime / heartbeat-defaults.ts
heartbeat-defaults.ts
 1  import type { AppSettings } from '@/types'
 2  
 3  export const DEFAULT_HEARTBEAT_INTERVAL_SEC = 1800
 4  export const DEFAULT_HEARTBEAT_ACK_MAX_CHARS = 300
 5  export const DEFAULT_HEARTBEAT_SHOW_OK = false
 6  export const DEFAULT_HEARTBEAT_SHOW_ALERTS = true
 7  
 8  function parseIntSetting(value: unknown, fallback: number, min: number, max: number): number {
 9    const parsed = typeof value === 'number'
10      ? value
11      : typeof value === 'string'
12        ? Number.parseInt(value, 10)
13        : Number.NaN
14    if (!Number.isFinite(parsed)) return fallback
15    return Math.max(min, Math.min(max, Math.trunc(parsed)))
16  }
17  
18  function parseBoolSetting(value: unknown, fallback: boolean): boolean {
19    if (typeof value === 'boolean') return value
20    if (typeof value === 'string') {
21      const normalized = value.trim().toLowerCase()
22      if (['1', 'true', 'yes', 'on'].includes(normalized)) return true
23      if (['0', 'false', 'no', 'off'].includes(normalized)) return false
24    }
25    return fallback
26  }
27  
28  export interface NormalizedHeartbeatSettingFields {
29    heartbeatIntervalSec: number
30    heartbeatAckMaxChars: number
31    heartbeatShowOk: boolean
32    heartbeatShowAlerts: boolean
33    heartbeatTarget: string | null
34    heartbeatPrompt: string | null
35  }
36  
37  export function normalizeHeartbeatSettingFields(
38    settings: Partial<AppSettings> | Record<string, unknown>,
39  ): NormalizedHeartbeatSettingFields {
40    return {
41      heartbeatIntervalSec: parseIntSetting(settings.heartbeatIntervalSec, DEFAULT_HEARTBEAT_INTERVAL_SEC, 0, 86_400),
42      heartbeatAckMaxChars: parseIntSetting(settings.heartbeatAckMaxChars, DEFAULT_HEARTBEAT_ACK_MAX_CHARS, 0, 8_000),
43      heartbeatShowOk: parseBoolSetting(settings.heartbeatShowOk, DEFAULT_HEARTBEAT_SHOW_OK),
44      heartbeatShowAlerts: parseBoolSetting(settings.heartbeatShowAlerts, DEFAULT_HEARTBEAT_SHOW_ALERTS),
45      heartbeatTarget: typeof settings.heartbeatTarget === 'string' && settings.heartbeatTarget.trim()
46        ? settings.heartbeatTarget.trim()
47        : null,
48      heartbeatPrompt: typeof settings.heartbeatPrompt === 'string' && settings.heartbeatPrompt.trim()
49        ? settings.heartbeatPrompt.trim()
50        : null,
51    }
52  }