// Common validation schemas reusable across modules import { z } from 'zod'; /** * Email validation schema */ export const emailSchema = z.string().email('Email inválido'); /** * Password validation schema * - Minimum 8 characters * - At least one uppercase letter * - At least one lowercase letter * - At least one number */ export const passwordSchema = z .string() .min(8, 'La contraseña debe tener al menos 8 caracteres') .regex(/[A-Z]/, 'Debe contener al menos una mayúscula') .regex(/[a-z]/, 'Debe contener al menos una minúscula') .regex(/[0-9]/, 'Debe contener al menos un número'); /** * Phone number validation schema * Supports international format with optional + */ export const phoneSchema = z .string() .regex(/^\+?[1-9]\d{1,14}$/, 'Número de teléfono inválido') .optional(); /** * URL validation schema */ export const urlSchema = z.string().url('URL inválida'); /** * Date validation schema with coercion */ export const dateSchema = z.coerce.date(); /** * Date range validation schema * Ensures end date is after start date */ export const dateRangeSchema = z .object({ start: z.coerce.date(), end: z.coerce.date(), }) .refine((data) => data.end > data.start, { message: 'La fecha de fin debe ser posterior a la fecha de inicio', path: ['end'], }); /** * Positive number schema */ export const positiveNumberSchema = z.number().positive('El valor debe ser mayor a 0'); /** * Non-empty string schema */ export const nonEmptyStringSchema = z.string().min(1, 'Este campo es requerido'); /** * Image file validation schema * - Max size: 5MB * - Allowed types: JPEG, PNG, WebP */ export const imageFileSchema = z .instanceof(File) .refine((file) => file.size <= 5 * 1024 * 1024, 'El archivo debe ser menor a 5MB') .refine( (file) => ['image/jpeg', 'image/png', 'image/webp'].includes(file.type), 'Solo se permiten imágenes JPEG, PNG o WebP' ); /** * Multiple image files schema */ export const imageFilesSchema = z .array(imageFileSchema) .min(1, 'Al menos una imagen es requerida') .max(10, 'Máximo 10 imágenes');