MCPcopy Create free account
hub / github.com/Dispatcharr/Dispatcharr / validateCronExpression

Function validateCronExpression

frontend/src/utils/cronUtils.js:8–63  ·  view source on GitHub ↗
(expression)

Source from the content-addressed store, hash-verified

6 */
7
8export function validateCronExpression(expression) {
9 if (!expression || expression.trim() === '') {
10 return { valid: false, error: 'Cron expression is required' };
11 }
12
13 const parts = expression.trim().split(/\s+/);
14 if (parts.length !== 5) {
15 return {
16 valid: false,
17 error:
18 'Cron expression must have exactly 5 parts: minute hour day month weekday',
19 };
20 }
21
22 const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
23
24 const cronPartRegex =
25 /^(\*\/\d+|\*|\d+(-\d+)?(\/\d+)?(,\d+(-\d+)?(\/\d+)?)*)$/;
26
27 const fields = [
28 { value: minute, label: 'minute', min: 0, max: 59 },
29 { value: hour, label: 'hour', min: 0, max: 23 },
30 { value: dayOfMonth, label: 'day', min: 1, max: 31 },
31 { value: month, label: 'month', min: 1, max: 12 },
32 { value: dayOfWeek, label: 'weekday', min: 0, max: 6 },
33 ];
34
35 for (const { value, label, min, max } of fields) {
36 if (!cronPartRegex.test(value)) {
37 return {
38 valid: false,
39 error: `Invalid ${label} field (${min}-${max}, *, or cron syntax)`,
40 };
41 }
42
43 // Extra numeric-range check for plain numbers
44 if (
45 !(
46 value === '*' ||
47 value.includes('/') ||
48 value.includes('-') ||
49 value.includes(',')
50 )
51 ) {
52 const num = parseInt(value, 10);
53 if (isNaN(num) || num < min || num > max) {
54 return {
55 valid: false,
56 error: `${label.charAt(0).toUpperCase() + label.slice(1)} must be between ${min} and ${max}`,
57 };
58 }
59 }
60 }
61
62 return { valid: true, error: null };
63}

Callers 3

ScheduleInputFunction · 0.90
handleCronChangeFunction · 0.90
BackupManagerFunction · 0.90

Calls 1

testMethod · 0.80

Tested by

no test coverage detected