All files / lib template-slots-validator.ts

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

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 36 37 38 39 40 41 42 43 44 45    2x             2x 2x   2x               2x             2x                   17x 17x 8x 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 };
}