(expr: string)
| 81 | * Returns null if invalid or unsupported syntax. |
| 82 | */ |
| 83 | export function parseCronExpression(expr: string): CronFields | null { |
| 84 | // Defensive against non-string input: ExecuteExtraTool passes raw params |
| 85 | // through to validateInput without re-running the target tool's schema, so |
| 86 | // a wrong field name (e.g. 'schedule' instead of 'cron') surfaces here as |
| 87 | // undefined. Without this guard, .trim() below throws "undefined is not an |
| 88 | // object" — every CronCreate call from ExecuteExtraTool fails identically. |
| 89 | if (typeof expr !== 'string') return null |
| 90 | const parts = expr.trim().split(/\s+/) |
| 91 | if (parts.length !== 5) return null |
| 92 | |
| 93 | const expanded: number[][] = [] |
| 94 | for (let i = 0; i < 5; i++) { |
| 95 | const result = expandField(parts[i]!, FIELD_RANGES[i]!) |
| 96 | if (!result) return null |
| 97 | expanded.push(result) |
| 98 | } |
| 99 | |
| 100 | return { |
| 101 | minute: expanded[0]!, |
| 102 | hour: expanded[1]!, |
| 103 | dayOfMonth: expanded[2]!, |
| 104 | month: expanded[3]!, |
| 105 | dayOfWeek: expanded[4]!, |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Compute the next Date strictly after `from` that matches the cron fields, |
no test coverage detected