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 }