import { Cron as CronerCron } from "croner" /** * @description Cron 计划模型的配置项。 */ export interface CronOptions { /** * @description 用于描述计划的 Cron 表达式或单次触发时点。 */ pattern: string | Date /** * @default false */ domAndDow?: boolean | undefined } /** * @description 用于围绕 Cron 计划计算运行时点并判断时间匹配关系的模型。 */ export class Cron { protected options: CronOptions protected croner: CronerCron /** * @description 使用给定配置创建一个 Cron 计划模型。 */ constructor(options: CronOptions) { this.options = options this.croner = new CronerCron(options.pattern, { domAndDow: options.domAndDow ?? false, alternativeWeekdays: false, }) } /** * @description 获取该计划最近一次运行时点。 */ prevRun(): Date | undefined { const prev = this.croner.previousRun() return prev === null ? undefined : prev } /** * @description 获取该计划最近若干次运行时点。 */ prevRuns(n: number): Date[] { const prevRuns = this.croner.previousRuns(n) return prevRuns } /** * @description 获取该计划当前运行时点。 */ currentRun(): Date | undefined { const current = this.croner.currentRun() return current === null ? undefined : current } /** * @description 获取该计划下一次运行时点。 */ nextRun(): Date | undefined { const next = this.croner.nextRun() return next === null ? undefined : next } /** * @description 获取该计划接下来若干次运行时点。 */ nextRuns(n: number): Date[] { const nextRuns = this.croner.nextRuns(n) return nextRuns } /** * @description 判断给定时间点是否匹配该计划。 */ match(date: Date): boolean { const isMatch = this.croner.match(date) return isMatch } } export const isCron = (value: unknown): value is Cron => { return value instanceof Cron }