diff --git a/__tests__/parseText/suites/smoke.txt b/__tests__/parseText/suites/smoke.txt index ccd7c90..c7d2e47 100644 --- a/__tests__/parseText/suites/smoke.txt +++ b/__tests__/parseText/suites/smoke.txt @@ -43,6 +43,10 @@ On Wednesday at 2:13pm Every week 0 9 * * 1 +Every month +0 9 1 * * + + Every weekd * * * * * diff --git a/package.json b/package.json index a1e6b13..cf63960 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "crontext", - "version": "0.2.4", + "version": "0.2.5", "description": "Simple utility for parsing human text into a cron schedule.", "files": [ "lib" diff --git a/src/parser.ts b/src/parser.ts index 017c505..79c1b9f 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -18,8 +18,17 @@ export const INIT = '_'; // Used to know whether the value has been set at all. export const DEFAULT_DAY_MINUTES = '0'; export const DEFAULT_DAY_HOURS = '9'; -const { FREQUENCY, NUMBER, MINUTE, CLOCK, DAY, HOUR, DAYS, RELATIVE_DAY } = - TokenType; +const { + FREQUENCY, + OCCURRENCE, + NUMBER, + MINUTE, + CLOCK, + DAY, + HOUR, + DAYS, + RELATIVE_DAY, +} = TokenType; const defaultParsed: Parsed = { minutes: INIT, @@ -29,6 +38,19 @@ const defaultParsed: Parsed = { month: INIT, }; +export const updateDay = ( + crontext: Parsed, + tokens: Token[], + options: Options, +): Parsed => { + // If there are no minutes or hour set we use defaults + // 'On monday' -> 9am Monday + if (crontext.minutes === INIT) crontext.minutes = options.defaultMinute; + if (crontext.hour === INIT) crontext.hour = options.defaultHour; + const dayOfWeek = getDayOfWeek(tokens[1].value); + return { ...crontext, dayOfWeek }; +}; + export const updateDays = ( crontext: Parsed, tokens: Token[], @@ -114,22 +136,33 @@ export const rules = [ }, }, { - match: [FREQUENCY, DAYS], + match: [OCCURRENCE, DAYS], update: updateDays, }, { - match: [FREQUENCY, NUMBER, DAYS], + match: [OCCURRENCE, NUMBER, DAYS], update: updateDays, }, + { + match: [OCCURRENCE, DAY], + update: updateDay, + }, { match: [FREQUENCY, DAY], + update: updateDay, + }, + { + match: [FREQUENCY, DAYS], update: (crontext: Parsed, tokens: Token[], options: Options): Parsed => { - // If there are no minutes or hour set we use defaults - // 'On monday' -> 9am Monday if (crontext.minutes === INIT) crontext.minutes = options.defaultMinute; if (crontext.hour === INIT) crontext.hour = options.defaultHour; - const dayOfWeek = getDayOfWeek(tokens[1].value); - return { ...crontext, dayOfWeek }; + if (tokens[1].value.indexOf('month') > -1) { + crontext.dayOfMonth = '1'; + } + if (tokens[1].value.indexOf('week') > -1) { + crontext.dayOfWeek = options.startOfWeek; + } + return crontext; }, }, { diff --git a/src/tokens/index.ts b/src/tokens/index.ts index c3ed1de..84c8c20 100644 --- a/src/tokens/index.ts +++ b/src/tokens/index.ts @@ -11,6 +11,7 @@ export enum TokenType { NUMBER = 'number', EXCLUDE = 'exclude', FREQUENCY = 'frequency', + OCCURRENCE = 'occurrence', DAY = 'day', DAYS = 'days', RELATIVE_DAY = 'relative day', @@ -52,8 +53,11 @@ export const tokens = { [TokenType.NUMBER]: { test: `^(\\d+|${numberStringRegexOptions})$|^a$`, }, + [TokenType.OCCURRENCE]: { + test: '^(in|next)$', + }, [TokenType.FREQUENCY]: { - test: '^(every|each|every other|at|on|in|next)$', + test: '^(every|each|every other|at|on)$', }, [TokenType.CLOCK]: { test: /^(\d?\d:\d\d|\d)[ ]?(am|pm|AM|PM)|\d\d:\d\d|midnight|noon$/,