From ab03900adf080da08a0b2a3628fd0dcf0af28420 Mon Sep 17 00:00:00 2001 From: schererleander Date: Wed, 2 Jul 2025 22:17:57 +0200 Subject: feat: add libraries and utilities --- src/lib/validation.ts | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/lib/validation.ts (limited to 'src/lib/validation.ts') diff --git a/src/lib/validation.ts b/src/lib/validation.ts new file mode 100644 index 0000000..02983e4 --- /dev/null +++ b/src/lib/validation.ts @@ -0,0 +1,72 @@ +import { z } from 'zod' + +export const registerSchema = z.object({ + name: z + .string() + .trim() + .min(2, 'Name must be at least 2 characters') + .max(50, 'Name must be at most 50 characters') + .regex(/^[a-zA-Z\s'-]+$/, 'Name can only contain letters, spaces, hyphens, and apostrophes'), + email: z + .string() + .trim() + .toLowerCase() + .email('Invalid email format') + .max(254, 'Email must be at most 254 characters'), + password: z + .string() + .min(8, 'Password must be at least 8 characters') + .max(128, 'Password must be at most 128 characters') + .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$/, + 'Password must contain at least one uppercase letter, one lowercase letter, and one number') +}) + +export const loginSchema = z.object({ + email: z + .string() + .trim() + .toLowerCase() + .email('Invalid email format') + .max(254, 'Email must be at most 254 characters'), + password: z + .string() + .max(128, 'Password must be at most 128 characters') +}) + +// Profile update schema (reusing name and email from registerSchema) +export const updateProfileSchema = z.object({ + name: registerSchema.shape.name, + email: registerSchema.shape.email, +}) + +// Password change schema (reusing password validation from registerSchema) +export const updatePasswordSchema = z.object({ + currentPassword: z.string().min(1, 'Current password is required'), + newPassword: registerSchema.shape.password, +}) + +// Type inference from schemas +export type RegisterInput = z.infer +export type LoginInput = z.infer +export type UpdateProfileInput = z.infer +export type UpdatePasswordInput = z.infer + +export const emailSchema = z.object({ + email: z + .string() + .trim() + .toLowerCase() + .email('Invalid email format') + .max(254, 'Email must be at most 254 characters') +}) + +export function formatZodError(error: z.ZodError) { + return error.errors.map(err => ({ + field: err.path.join('.'), + message: err.message + })) +} + +export function getFirstErrorMessage(error: z.ZodError): string { + return error.errors[0]?.message || 'Validation failed' +} \ No newline at end of file -- cgit v1.3.1