import { parseT } from '$lib/time'; import type { Shifts } from '$lib/shifts'; export type { Shifts }; const IPV4 = /^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/; // A DNS label: alphanumeric, hyphens allowed in the middle, 1-63 chars. const LABEL = '[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?'; const HOSTNAME = new RegExp(`^${LABEL}(?:\\.${LABEL})*$`); /** Whether `v` is a usable time clock address: an IPv4 address, a bare * hostname (e.g. "timbratore") or a FQDN (e.g. "timbratore.lan"). */ export const isValidHost = (v: string): boolean => IPV4.test(v) || HOSTNAME.test(v); /** The 4 time fields of `Shifts` — everything but `round_step_min`, which isn't a time. */ export type ShiftTimeKey = 'in1' | 'out1' | 'in2' | 'out2'; export const SHIFT_ROWS: { titleKey: string; a: ShiftTimeKey; b: ShiftTimeKey }[] = [ { titleKey: 'settings.shift_1', a: 'in1', b: 'out1' }, { titleKey: 'settings.shift_2', a: 'in2', b: 'out2' } ]; export interface ShiftCheck { minutes: Record | null; bad: Partial>; errorKey: string | null; } export function checkShifts(shifts: Shifts): ShiftCheck { const t: Record = { in1: parseT(shifts.in1), out1: parseT(shifts.out1), in2: parseT(shifts.in2), out2: parseT(shifts.out2) }; const bad: Partial> = {}; for (const key of Object.keys(t) as ShiftTimeKey[]) { if (t[key] === null) bad[key] = true; } if (Object.keys(bad).length) return { minutes: null, bad, errorKey: 'settings.shift_error_format' }; const n = t as Record; if (n.out1 <= n.in1) return { minutes: null, bad: { out1: true }, errorKey: 'settings.shift_error_out1' }; if (n.in2 < n.out1) return { minutes: null, bad: { in2: true }, errorKey: 'settings.shift_error_in2' }; if (n.out2 <= n.in2) return { minutes: null, bad: { out2: true }, errorKey: 'settings.shift_error_out2' }; return { minutes: n, bad: {}, errorKey: null }; } export const roundValid = (v: string): boolean => /^\d{1,2}$/.test(v) && Number(v) >= 1 && Number(v) <= 60;