profile: z.object({ name: z.string({ error: 'The profile.name field is required.' }).trim().refine((val) => val != undefined && val != null && val != '', { error: 'The profile.name field is required.' }).min(1, 'The profile.name field is required.').max(150, 'The profile.name field must not be greater than 150 characters.'), bio: z.string().max(500, 'The profile.bio field must not be greater than 500 characters.').trim().nullable().optional(), website: z.preprocess((val) => (val === '' ? undefined : val), z.url({ error: 'The profile.website field must be a valid URL.' }).nullable().optional()), timezone: z.string({ error: 'The profile.timezone field is required.' }).trim().refine((val) => val != undefined && val != null && val != '', { error: 'The profile.timezone field is required.' }).min(1, 'The profile.timezone field is required.'), preferences: z.object({ accepted_terms: z.string().refine((val) => { if (val === undefined || val === null) { return false; } if (typeof val === "string") { const normalized = val.toLowerCase(); if (normalized === "yes" || normalized === "on" || normalized === "true" || normalized === "1") { return true; } } return val === true || val === 1; }, { message: 'You must accept the terms.' }).trim().optional(), tags: z.array(z.enum(["news", "updates", "offers"])).min(1, 'The profile.preferences.tags field must have at least 1 items.').max(5, 'The profile.preferences.tags field must not have more than 5 items.').refine((values) => { if (!Array.isArray(values)) { return true; } const ignoreCase = false; const strict = false; for (let i = 0; i < values.length; i++) { for (let j = i + 1; j < values.length; j++) { const left = values[i]; const right = values[j]; if (ignoreCase && typeof left === "string" && typeof right === "string") { if (left.localeCompare(right, undefined, { sensitivity: "accent" }) === 0) { return false; } continue; } if (strict ? left === right : left == right) { return false; } } } return true; }, { message: 'The profile.preferences.tags field has a duplicate value.' }).optional() }).optional(), contacts: z.array(z.object({ email: z.email({ error: 'The profile.contacts.*.email field must be a valid email address.' }).trim().min(1, 'The profile.contacts.*.email field is required.'), phone: z.string().trim().nullable().optional(), label: z.enum(["primary", "backup"], { message: "The profile.contacts.*.label field is required." }) })).min(1, 'The profile.contacts field must have at least 1 items.').optional(), address: z.object({ street: z.string({ error: 'The profile.address.street field is required.' }).trim().refine((val) => val != undefined && val != null && val != '', { error: 'The profile.address.street field is required.' }).min(1, 'The profile.address.street field is required.'), city: z.string({ error: 'The profile.address.city field is required.' }).trim().refine((val) => val != undefined && val != null && val != '', { error: 'The profile.address.city field is required.' }).min(1, 'The profile.address.city field is required.'), postal_code: z.string({ error: 'The profile.address.postal code field is required.' }).trim().refine((val) => val != undefined && val != null && val != '', { error: 'The profile.address.postal code field is required.' }).min(1, 'The profile.address.postal code field is required.').regex(/^[0-9]{5}$/, 'Postal code must be exactly 5 digits.'), country: z.string({ error: 'The profile.address.country field is required.' }).trim().refine((val) => val != undefined && val != null && val != '', { error: 'The profile.address.country field is required.' }).min(1, 'The profile.address.country field is required.').length(2, 'The profile.address.country field must be 2 characters.') }).optional() }).optional(),
0 commit comments