UNPKG

material-ui-cron

Version:
305 lines (273 loc) 11 kB
import { DEFAULT_DAY_OF_MONTH_OPTS, DEFAULT_MINUTE_OPTS } from './constants'; export const getIndex = (obj, arr) => { return arr.findIndex(x => x.value === obj.value); }; export const getTimeIndex = obj => { return getIndex(obj, getTimesOfTheDay()); }; export const getMinutesIndex = obj => { return getIndex(obj, DEFAULT_MINUTE_OPTS); }; export const getPeriodIndex = obj => { if (obj.value === 'hour') { return 0; } else if (obj.value === 'day') { return 1; } else if (obj.value === 'week') { return 2; } else if (obj.value === 'month') { return 3; } return 4; }; export const getDayOfMonthIndex = obj => { return getIndex(obj, DEFAULT_DAY_OF_MONTH_OPTS); }; export const getSortedOptions = options => { return options.sort((a, b) => Number(a.value) - Number(b.value)); }; export const isIncreasingSequence = options => options.every((option, i) => i === 0 || Number(options[i - 1].value) + 1 === Number(option.value)); export function isAscending(arr) { return arr.every(function (x, i) { return i === 0 || Number(x) >= Number(arr[i - 1]); }); } export function getTimesOfTheDayList() { const hours = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; const periods = ['AM', 'PM']; return periods.flatMap(period => hours.map(hour => hour > 9 ? `${hour}:00 ${period}` : `0${hour}:00 ${period}`)); } export function getTimesOfTheDay() { return getTimesOfTheDayList().map(time => ({ value: time, label: time })); } export const hasValidCronParts = cronExp => cronExp.split(' ').length === 5; export const getNumbersInCronPart = part => { let numbers = []; let tmpNumber = ''; for (let i = 0; i < part.length; i++) { let num = Number(part[i]); if (num >= 0 && num <= 9) { tmpNumber += num; } else { if (tmpNumber.length > 0) { numbers.push(tmpNumber); } tmpNumber = ''; } } if (tmpNumber.length > 0) { numbers.push(tmpNumber); } return numbers.map(part => Number(part)); }; export const doesNumberStartWithZero = part => { let tmpNumber = ''; for (let i = 0; i < part.length; i++) { let num = Number(part[i]); if (num >= 0 && num <= 9) { tmpNumber += num; } else { if (tmpNumber.startsWith('0') && tmpNumber.length > 1) { return true; } tmpNumber = ''; } } if (tmpNumber.startsWith('0') && tmpNumber.length > 1) { return true; } return false; }; export const hasValidNumbersInCronPart = (part, condition) => { return getNumbersInCronPart(part).every(num => condition(num)); }; export function hasNoDuplicates(part) { const subparts = part.split('/'); return subparts.every(subpart => { let numArr = getNumbersInCronPart(subpart); return new Set(numArr).size === numArr.length; }); } export const REGEX_ALL = /^([*])\/([1-9]{1})([0-9]{0,1})$/; export const REGEX_EVERY = /^([0-9]{1,4})\/([1-9]{1,2})$/; export const REGEX_EVERY_HYPEN = /^([0-9]{1,2}-[0-9]{1,2})\/([1-9]{1})?([0-9]{1})$/; export const REGEX_COMMA = /^[0-9]{1,2}(,[0-9]{1,2})+$/; export const REGEX_HYPHEN = /^([0-9]{1,2}-[0-9]{1,2})$/; export const REGEX_SINGLE_DIGIT = /^([0-9]{1,2})$/; export const REGEX_SINGLE_ALL = /^([*]{1})$/; export const REGEX_SINGLE_SPL = /^([L]{1})$/; export const CRON_VALIDATION = (isValid, message) => { return { isValid, message }; }; export const isValidMinutePart = cronExp => { const part = cronExp.split(' ')[0]; if (doesNumberStartWithZero(part)) { return CRON_VALIDATION(false, 'Number starts with zero'); } else if (!hasValidNumbersInCronPart(part, num => num >= 0 && num <= 59)) { return CRON_VALIDATION(false, 'Number should be between 0 and 59'); } else if (!hasNoDuplicates(part)) { return CRON_VALIDATION(false, 'Duplicate numbers not allowed'); } else if (part.indexOf('/') > 0) { if (part.split('/')[0] !== '*' && isAscending(part.split('/')[0].split('-'))) { return CRON_VALIDATION(REGEX_EVERY_HYPEN.test(part), 'Incorrect syntax hypen'); } else if (part.indexOf('-') > 0) { return CRON_VALIDATION(false, 'Incorrect range'); } else { return CRON_VALIDATION(REGEX_ALL.test(part), 'Incorrect syntax'); } } else if (part.indexOf(',') > 0) { return CRON_VALIDATION(REGEX_COMMA.test(part), 'Invalid syntax'); } else if (part.indexOf('-') > 0) { if (isAscending(part.split('-'))) { return CRON_VALIDATION(REGEX_HYPHEN.test(part), 'Invalid range'); } else { return CRON_VALIDATION(false, 'Invalid range'); } } else if (REGEX_SINGLE_DIGIT.test(part)) { return CRON_VALIDATION(true, 'Invalid single digit'); } return CRON_VALIDATION(REGEX_SINGLE_ALL.test(part), 'Invalid single all'); }; export const isValidHourPart = cronExp => { const part = cronExp.split(' ')[1]; if (doesNumberStartWithZero(part)) { return CRON_VALIDATION(false, 'Number starts with zero'); } else if (!hasValidNumbersInCronPart(part, num => num >= 0 && num <= 23)) { return CRON_VALIDATION(false, 'Number should be between 0 and 23'); } else if (!hasNoDuplicates(part)) { return CRON_VALIDATION(false, 'Duplicate numbers not allowed'); } else if (part.indexOf('/') > 0) { if (part.split('/')[0] !== '*' && isAscending(part.split('/')[0].split('-'))) { return CRON_VALIDATION(REGEX_EVERY_HYPEN.test(part), 'Incorrect syntax hypen'); } else if (part.indexOf('-') > 0) { return CRON_VALIDATION(false, 'Incorrect range'); } else { return CRON_VALIDATION(REGEX_ALL.test(part), 'Incorrect syntax'); } } else if (part.indexOf(',') > 0) { return CRON_VALIDATION(REGEX_COMMA.test(part), 'Invalid syntax'); } else if (part.indexOf('-') > 0) { if (isAscending(part.split('-'))) { return CRON_VALIDATION(REGEX_HYPHEN.test(part), 'Invalid range'); } else { return CRON_VALIDATION(false, 'Invalid range'); } } else if (REGEX_SINGLE_DIGIT.test(part)) { return CRON_VALIDATION(true, 'Invalid single digit'); } return CRON_VALIDATION(REGEX_SINGLE_ALL.test(part), 'Invalid single all'); }; export const isValidDayOfMonthPart = cronExp => { const part = cronExp.split(' ')[2]; if (doesNumberStartWithZero(part)) { return CRON_VALIDATION(false, 'Number starts with zero'); } else if (!hasValidNumbersInCronPart(part, num => num >= 1 && num <= 31)) { return CRON_VALIDATION(false, 'Number should be between 1 and 31'); } else if (!hasNoDuplicates(part)) { return CRON_VALIDATION(false, 'Duplicate numbers not allowed'); } else if (part.indexOf('/') > 0) { if (part.split('/')[0] !== '*' && isAscending(part.split('/')[0].split('-'))) { return CRON_VALIDATION(REGEX_EVERY_HYPEN.test(part), 'Incorrect syntax hypen'); } else if (part.indexOf('-') > 0) { return CRON_VALIDATION(false, 'Incorrect range'); } else { return CRON_VALIDATION(REGEX_ALL.test(part), 'Incorrect syntax'); } } else if (part.indexOf(',') > 0) { return CRON_VALIDATION(REGEX_COMMA.test(part), 'Invalid syntax'); } else if (part.indexOf('-') > 0) { if (isAscending(part.split('-'))) { return CRON_VALIDATION(REGEX_HYPHEN.test(part), 'Invalid range'); } else { return CRON_VALIDATION(false, 'Invalid range'); } } else if (REGEX_SINGLE_DIGIT.test(part)) { return CRON_VALIDATION(true, ''); } else if (REGEX_SINGLE_SPL.test(part)) { return CRON_VALIDATION(true, ''); } return CRON_VALIDATION(REGEX_SINGLE_ALL.test(part), 'Invalid single all'); }; export const isValidDayOfWeekPart = cronExp => { const part = cronExp.split(' ')[4]; if (doesNumberStartWithZero(part)) { return CRON_VALIDATION(false, 'Number starts with zero'); } else if (!hasValidNumbersInCronPart(part, num => num >= 0 && num <= 6)) { return CRON_VALIDATION(false, 'Number should be between 0 and 6'); } else if (!hasNoDuplicates(part)) { return CRON_VALIDATION(false, 'Duplicate numbers not allowed'); } else if (part.indexOf(',') > 0) { return CRON_VALIDATION(REGEX_COMMA.test(part), 'Invalid syntax'); } else if (part.indexOf('-') > 0) { if (isAscending(part.split('-'))) { return CRON_VALIDATION(REGEX_HYPHEN.test(part), 'Incorrect syntax hypen'); } else { return CRON_VALIDATION(false, 'Range should be low to high'); } } else if (REGEX_SINGLE_DIGIT.test(part)) { return CRON_VALIDATION(true, 'Invalid single digit'); } return CRON_VALIDATION(REGEX_SINGLE_ALL.test(part), 'Invalid single all'); }; export const isValidMonthPart = cronExp => { const part = cronExp.split(' ')[3]; if (doesNumberStartWithZero(part)) { return CRON_VALIDATION(false, 'Number starts with zero'); } else if (!hasValidNumbersInCronPart(part, num => num >= 1 && num <= 12)) { return CRON_VALIDATION(false, 'Number should be between 0 and 6'); } else if (!hasNoDuplicates(part)) { return CRON_VALIDATION(false, 'Duplicate numbers not allowed'); } else if (part.indexOf(',') > 0) { return CRON_VALIDATION(REGEX_COMMA.test(part), 'Invalid syntax'); } else if (part.indexOf('-') > 0) { if (isAscending(part.split('-'))) { return CRON_VALIDATION(REGEX_HYPHEN.test(part), 'Incorrect syntax hypen'); } else { return CRON_VALIDATION(false, 'Range should be low to high'); } } else if (REGEX_SINGLE_DIGIT.test(part)) { return CRON_VALIDATION(true, 'Invalid single digit'); } return CRON_VALIDATION(REGEX_SINGLE_ALL.test(part), 'Invalid single all'); }; export const getCronStatus = (msg, hasError) => ({ hasError: hasError, message: msg }); export const validateCronExp = cronExp => { if (!hasValidCronParts(cronExp)) { return getCronStatus('Cron should have 5 parts', true); } const minuteValidation = isValidMinutePart(cronExp); if (!minuteValidation.isValid) { return getCronStatus(`Invalid minute cron part: ${minuteValidation.message}`, true); } const hourValidation = isValidHourPart(cronExp); if (!hourValidation.isValid) { return getCronStatus(`Invalid hour cron part: ${hourValidation.message}`, true); } const dayOfMonthValidation = isValidDayOfMonthPart(cronExp); if (!dayOfMonthValidation.isValid) { return getCronStatus(`Invalid day of month cron part: ${dayOfMonthValidation.message}`, true); } const monthValidation = isValidMonthPart(cronExp); if (!monthValidation.isValid) { return getCronStatus(`Invalid month cron part: ${monthValidation.message}`, true); } const dayOfWeekValidation = isValidDayOfWeekPart(cronExp); if (!dayOfWeekValidation.isValid) { return getCronStatus(`Invalid day of week cron part: ${dayOfWeekValidation.message}`, true); } return getCronStatus('', false); }; export const countOccurrences = (arr, val) => arr.reduce((a, v) => v === val ? a + 1 : a, 0); export function range(start, end, step = 1) { const len = Math.floor((end - start) / step) + 1; return Array(len).fill('00').map((_, idx) => `${start + idx * step}`); }