All files / lib template-slots-validator.ts

100% Statements 12/12
100% Branches 2/2
100% Functions 2/2
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35    2x 2x 2x   2x               2x             2x               17x 17x 9x 8x    
import { z } from "zod";
 
const TRANSITIONS = ["fade", "slide_left", "slide_right", "zoom", "none"] as const;
const POSITIONS = ["top", "center", "bottom"] as const;
const PHOTO_TYPES = ["before", "after"] as const;
 
export const templatePhotoSlotSchema = z.object({
	slotIndex: z.number().int().min(0).optional(),
	label: z.string().min(1).max(50),
	durationS: z.number().positive().min(1).max(10),
	transition: z.enum(TRANSITIONS),
	photoType: z.enum(PHOTO_TYPES).nullable().optional(),
});
 
export const templateTextOverlaySchema = z.object({
	text: z.string().min(1).max(200),
	position: z.enum(POSITIONS),
	durationS: z.number().positive().min(1).max(5),
	afterSlot: z.number().int().min(0),
});
 
export const templateSlotsSchema = z.object({
	photoSlots: z.array(templatePhotoSlotSchema).min(1).max(20),
	textOverlays: z.array(templateTextOverlaySchema).optional(),
});
 
export function validateTemplateSlots(
	input: unknown,
): { success: true; data: z.infer<typeof templateSlotsSchema> } | { success: false; error: string } {
	const result = templateSlotsSchema.safeParse(input);
	if (result.success) return { success: true, data: result.data };
	const messages = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
	return { success: false, error: messages };
}