52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import { z } from "zod";
|
|
|
|
export const ScheduledTodoTitleSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(1, "Title is required")
|
|
.max(100, "Title must be 100 characters or fewer");
|
|
|
|
export const ScheduledTodoDetailsSchema = z.string().max(5_000).optional();
|
|
|
|
const DateStringSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid date");
|
|
|
|
const RecurrenceEndSchema = z.discriminatedUnion("type", [
|
|
z.object({ type: z.literal("never") }),
|
|
z.object({ type: z.literal("until"), date: DateStringSchema }),
|
|
z.object({ type: z.literal("count"), count: z.number().int().min(1).max(999) }),
|
|
]);
|
|
|
|
/**
|
|
* What the "Add/Edit Scheduled To-Do" dialog submits for the recurring
|
|
* case -- validated here and only here turned into an RFC 5545 RRULE
|
|
* string (see lib/rrule-utils.ts). Never trust a client-supplied RRULE
|
|
* string directly.
|
|
*/
|
|
export const RecurrenceInputSchema = z
|
|
.object({
|
|
frequency: z.enum(["DAILY", "WEEKLY", "MONTHLY", "YEARLY"]),
|
|
interval: z.number().int().min(1).max(365),
|
|
// 0 = Sunday .. 6 = Saturday, matching Date#getUTCDay().
|
|
daysOfWeek: z.array(z.number().int().min(0).max(6)).max(7).optional(),
|
|
dayOfMonth: z.number().int().min(1).max(31).optional(),
|
|
month: z.number().int().min(1).max(12).optional(),
|
|
end: RecurrenceEndSchema,
|
|
})
|
|
.superRefine((value, ctx) => {
|
|
if (value.frequency === "WEEKLY" && !value.daysOfWeek?.length) {
|
|
ctx.addIssue({
|
|
code: "custom",
|
|
path: ["daysOfWeek"],
|
|
message: "Pick at least one day of the week",
|
|
});
|
|
}
|
|
if ((value.frequency === "MONTHLY" || value.frequency === "YEARLY") && !value.dayOfMonth) {
|
|
ctx.addIssue({ code: "custom", path: ["dayOfMonth"], message: "Day of month is required" });
|
|
}
|
|
if (value.frequency === "YEARLY" && !value.month) {
|
|
ctx.addIssue({ code: "custom", path: ["month"], message: "Month is required" });
|
|
}
|
|
});
|
|
|
|
export type RecurrenceInput = z.infer<typeof RecurrenceInputSchema>;
|