42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { z } from "zod"
|
|
|
|
// Treats null/undefined as missing so validation surfaces one clear
|
|
// "required" message instead of a generic type error.
|
|
function requiredString(message: string) {
|
|
return z.preprocess(
|
|
(val) => (val === null || val === undefined ? "" : val),
|
|
z.string().min(1, message)
|
|
)
|
|
}
|
|
|
|
// Email validation schema
|
|
export const emailSchema = z.preprocess(
|
|
(val) => (val === null || val === undefined ? "" : val),
|
|
z.string().min(1, "Email is required").email("Enter a valid email")
|
|
)
|
|
|
|
// Login schema (email + password) for reuse across the app.
|
|
// Password strength is intentionally NOT re-validated here: an existing
|
|
// account's password may predate current complexity rules, and only the
|
|
// server can judge whether credentials are actually correct. Complexity
|
|
// rules belong on registration/reset-password, not on login.
|
|
export const loginSchema = z.object({
|
|
email: emailSchema,
|
|
password: requiredString("Password is required"),
|
|
})
|
|
|
|
export type LoginValues = z.infer<typeof loginSchema>
|
|
|
|
// Helper to validate email synchronously
|
|
export function validateEmail(value: unknown) {
|
|
const result = emailSchema.safeParse(value)
|
|
return result.success ? { valid: true, value: result.data } : { valid: false, error: result.error }
|
|
}
|
|
|
|
export default {
|
|
emailSchema,
|
|
loginSchema,
|
|
validateEmail,
|
|
}
|
|
|