All files / src/web/webview validators.ts

100% Statements 21/21
100% Branches 24/24
100% Functions 8/8
100% Lines 14/14

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 (${...})';
}