mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-02-08 20:41:58 -05:00
* feat(schedule-form): allow custom cron expression * refactor: guard against potential undefined cron expression
97 lines
2.0 KiB
TypeScript
97 lines
2.0 KiB
TypeScript
export type CronFormValues = {
|
|
frequency: string;
|
|
dailyTime?: string;
|
|
weeklyDay?: string;
|
|
monthlyDays?: string[];
|
|
cronExpression?: string;
|
|
};
|
|
|
|
const isSimpleNumber = (s: string) => /^\d+$/.test(s);
|
|
const isWildcard = (s: string) => s === "*";
|
|
|
|
type Matcher = (parts: string[]) => CronFormValues | null;
|
|
|
|
const matchers: Matcher[] = [
|
|
// Hourly: 0 * * * *
|
|
(parts) => {
|
|
if (parts.length === 5 && parts[0] === "0" && parts.slice(1).every(isWildcard)) {
|
|
return { frequency: "hourly" };
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// Daily: mm hh * * *
|
|
(parts) => {
|
|
if (
|
|
parts.length === 5 &&
|
|
isSimpleNumber(parts[0]) &&
|
|
isSimpleNumber(parts[1]) &&
|
|
parts.slice(2).every(isWildcard)
|
|
) {
|
|
return {
|
|
frequency: "daily",
|
|
dailyTime: `${parts[1].padStart(2, "0")}:${parts[0].padStart(2, "0")}`,
|
|
};
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// Weekly: mm hh * * d
|
|
(parts) => {
|
|
if (
|
|
parts.length === 5 &&
|
|
isSimpleNumber(parts[0]) &&
|
|
isSimpleNumber(parts[1]) &&
|
|
isWildcard(parts[2]) &&
|
|
isWildcard(parts[3]) &&
|
|
isSimpleNumber(parts[4])
|
|
) {
|
|
return {
|
|
frequency: "weekly",
|
|
dailyTime: `${parts[1].padStart(2, "0")}:${parts[0].padStart(2, "0")}`,
|
|
weeklyDay: parts[4],
|
|
};
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// Monthly: mm hh dd * *
|
|
(parts) => {
|
|
if (
|
|
parts.length === 5 &&
|
|
isSimpleNumber(parts[0]) &&
|
|
isSimpleNumber(parts[1]) &&
|
|
parts[2] !== "*" &&
|
|
parts[2].split(",").every(isSimpleNumber) &&
|
|
isWildcard(parts[3]) &&
|
|
isWildcard(parts[4])
|
|
) {
|
|
return {
|
|
frequency: "monthly",
|
|
dailyTime: `${parts[1].padStart(2, "0")}:${parts[0].padStart(2, "0")}`,
|
|
monthlyDays: parts[2].split(","),
|
|
};
|
|
}
|
|
return null;
|
|
},
|
|
];
|
|
|
|
export const cronToFormValues = (cronExpression: string): CronFormValues => {
|
|
if (!cronExpression) {
|
|
return { frequency: "hourly" };
|
|
}
|
|
|
|
const normalized = cronExpression.trim().replace(/\s+/g, " ");
|
|
const parts = normalized.split(" ");
|
|
|
|
for (const matcher of matchers) {
|
|
const result = matcher(parts);
|
|
if (result) return result;
|
|
}
|
|
|
|
return {
|
|
frequency: "cron",
|
|
cronExpression: normalized,
|
|
};
|
|
};
|