UNPKG

moment-recur-ts

Version:

A momentjs plugin for matching and generating recurring dates.

147 lines (127 loc) 3.52 kB
import * as moment from 'moment' import { Calendar } from './calendar' import { Interval } from './interval' export namespace Rule { export type MeasureSingle = 'day' | 'week' | 'month' | 'year' | 'dayOfWeek' | 'dayOfMonth' | 'weekOfMonth' | 'weekOfMonthByDay' | 'weekOfYear' | 'monthOfYear' export type MeasurePlural = 'days' | 'weeks' | 'months' | 'years' | 'daysOfWeek' | 'daysOfMonth' | 'weeksOfMonth' | 'weeksOfMonthByDay' | 'weeksOfYear' | 'monthsOfYear' /** * @internal * @hidden */ export const MeasureSingleToPlural: { [m: string]: MeasurePlural } = { day: 'days', week: 'weeks', month: 'months', year: 'years', dayOfWeek: 'daysOfWeek', dayOfMonth: 'daysOfMonth', weekOfMonth: 'weeksOfMonth', weekOfMonthByDay: 'weeksOfMonthByDay', weekOfYear: 'weeksOfYear', monthOfYear: 'monthsOfYear' } export type UnitsInput = string | number | (string | number)[] | UnitsObject | undefined | null /** * @hidden * @deprecated */ export interface UnitsObject { [unit: string]: boolean [unit: number]: boolean } export type MeasureInput = MeasureSingle | MeasurePlural | undefined | null /** * @internal * @hidden */ export function factory (units: UnitsInput, measure: MeasureInput, start: moment.Moment | null): Rule { const normMeasure = normalizeMeasure(measure) switch (normMeasure) { case 'days': case 'weeks': case 'months': case 'years': return new Interval(unitsToArray(units), normMeasure, start) case 'daysOfWeek': case 'daysOfMonth': case 'weeksOfMonth': case 'weeksOfMonthByDay': case 'weeksOfYear': case 'monthsOfYear': return new Calendar(unitsToArray(units), normMeasure) } } /** * @internal * @hidden */ function unitsToArray (units: UnitsInput): (string | number)[] { if (units == null) { throw new Error('Units not defined for recurrence rule.') } else if (Array.isArray(units)) { return units } else if (typeof units === 'object') { return Object.keys(units) } else if (typeof units === 'number') { return [units] // tslint:disable-next-line:strict-type-predicates } else if (typeof units === 'string') { return [units] } else { throw new Error('Provide an array, object, string or number when passing units!') } } /** * Private function to pluralize measure names for use with dictionaries. * @internal * @hidden */ export function normalizeMeasure (measure: any): MeasurePlural { if (typeof measure === 'string') { if (MeasureSingleToPlural[measure]) { return MeasureSingleToPlural[measure] } else { for (const key in MeasureSingleToPlural) { if (MeasureSingleToPlural[key] === measure) return measure } } } throw new Error('Invalid Measure for recurrence: ' + measure) } } /** * */ export interface Rule { readonly units: number[] readonly measure: Rule.MeasurePlural /** * @internal * @hidden */ match (date: moment.Moment): boolean next (current: moment.Moment, limit?: moment.Moment): moment.Moment previous (current: moment.Moment, limit?: moment.Moment): moment.Moment }