Skip to content

feat(v4): cron expression validation#5730

Open
ysknsid25 wants to merge 1 commit intocolinhacks:mainfrom
ysknsid25:feat/cron
Open

feat(v4): cron expression validation#5730
ysknsid25 wants to merge 1 commit intocolinhacks:mainfrom
ysknsid25:feat/cron

Conversation

@ysknsid25
Copy link
Copy Markdown

Overview

This PR adds a new built-in string format validator z.cron() for validating standard 5-field cron expressions (minute, hour, day-of-month, month, day-of-week).

Why this is useful

Cron expressions are widely used in task scheduling, CI/CD pipelines, cloud functions (AWS EventBridge, GCP Cloud Scheduler, etc.), and configuration files. Validating them at the schema layer catches malformed expressions before they reach the scheduler, preventing silent failures or unexpected behavior at runtime.

Before this PR, users had to reach for a custom .refine() with a hand-written regex or a third-party package:

// Before: verbose and error-prone
const schema = z.string().refine(val => /^(\*|[0-5]?\d).../.test(val), {
  message: "Invalid cron expression",
});

With z.cron(), this is a single, well-tested, semantically clear call.

Usage

Standalone schema

import { z } from "zod";

const CronJob = z.object({
  name: z.string(),
  schedule: z.cron(),
});

CronJob.parse({ name: "cleanup", schedule: "0 2 * * *" }); // OK
CronJob.parse({ name: "cleanup", schedule: "60 * * * *" }); // NG. minute out of range

As a string check

z.string().cron();

Supported syntax

z.cron().parse("* * * * *");        // wildcard
z.cron().parse("0 9-17 * * 1-5");   // ranges (weekdays 9am–5pm)
z.cron().parse("*/15 * * * *");     // steps (every 15 min)
z.cron().parse("0 0 1,15 * *");     // lists (1st and 15th)
z.cron().parse("0-30/5 * * * *");   // combined (every 5 min for first 30 min)

Signed-off-by: ysknsid25 <kengo071225@gmail.com>
@ysknsid25 ysknsid25 changed the title feat: cron expression validation feat(v4): cron expression validation Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant