Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 13x 11x 7x 3x 12x 3x 8x 8x 16x 14x 3x 9x 7x 3x | export function validateId(value: string): string | null {
if (!value.trim()) { return 'ID is required'; }
if (!/^[a-zA-Z_][\w.-]*$/.test(value.trim())) { return 'Invalid ID format (must start with letter or underscore)'; }
return null;
}
export function validateRequired(label: string): (value: string) => string | null {
return (value: string) => value.trim() ? null : `${label} is required`;
}
function isIsoDate(value: string): boolean {
return /^\d{4}-\d{2}-\d{2}$/.test(value);
}
function isIsoTime(value: string): boolean {
return /^\d{2}:\d{2}(?::\d{2})?(?:Z|[+-]\d{2}:\d{2})?$/.test(value);
}
function isIsoDateTime(value: string): boolean {
const [datePart, timePart, ...rest] = value.split('T');
return rest.length === 0 && Boolean(timePart) && isIsoDate(datePart) && isIsoTime(timePart);
}
export function validateTimerValue(value: string): string | null {
if (!value.trim()) { return null; }
// Accept ISO 8601 durations, dates, repeat patterns, and expressions
if (/^(R\d*\/)?P[\dYMDTHS.]+$/.test(value) || isIsoDate(value) || isIsoDateTime(value) || /^\$\{.+\}$/.test(value)) { return null; }
return 'Expected ISO 8601 duration (PT5M), date (2026-12-31T23:59), repeat (R3/PT10M), or expression (${...})';
}
export function validateRetryCycle(value: string): string | null {
if (!value.trim()) { return null; }
if (/^R\d*\/P[\dYMDTHS.]+$/.test(value) || /^\$\{.+\}$/.test(value)) { return null; }
return 'Expected repeat pattern (R3/PT10M) or expression (${...})';
}
|