77 lines
3.1 KiB
TypeScript
77 lines
3.1 KiB
TypeScript
/**
|
|
* Common Domain - Schemas
|
|
*
|
|
* Shared validation primitives used across all domains.
|
|
*/
|
|
|
|
import { z } from "zod";
|
|
|
|
export const emailSchema = z
|
|
.string()
|
|
.email("Please enter a valid email address")
|
|
.toLowerCase()
|
|
.trim();
|
|
|
|
export const passwordSchema = z
|
|
.string()
|
|
.min(8, "Password must be at least 8 characters")
|
|
.regex(/[A-Z]/, "Password must contain at least one uppercase letter")
|
|
.regex(/[a-z]/, "Password must contain at least one lowercase letter")
|
|
.regex(/[0-9]/, "Password must contain at least one number")
|
|
.regex(/[^A-Za-z0-9]/, "Password must contain at least one special character");
|
|
|
|
export const nameSchema = z.string().min(1, "Name is required").max(100, "Name must be less than 100 characters").trim();
|
|
|
|
export const phoneSchema = z
|
|
.string()
|
|
.regex(/^[+]?[0-9\s\-()]{7,20}$/u, "Please enter a valid phone number")
|
|
.trim();
|
|
|
|
export const addressSchema = z.object({
|
|
street: z.string().max(200, "Street address is too long").nullable(),
|
|
streetLine2: z.string().max(200, "Street address line 2 is too long").nullable(),
|
|
city: z.string().max(100, "City name is too long").nullable(),
|
|
state: z.string().max(100, "State/Prefecture name is too long").nullable(),
|
|
postalCode: z.string().max(20, "Postal code is too long").nullable(),
|
|
country: z.string().max(100, "Country name is too long").nullable(),
|
|
});
|
|
|
|
export const requiredAddressSchema = z.object({
|
|
street: z.string().min(1, "Street address is required").max(200, "Street address is too long").trim(),
|
|
streetLine2: z.string().max(200, "Street address line 2 is too long").optional(),
|
|
city: z.string().min(1, "City is required").max(100, "City name is too long").trim(),
|
|
state: z
|
|
.string()
|
|
.min(1, "State/Prefecture is required")
|
|
.max(100, "State/Prefecture name is too long")
|
|
.trim(),
|
|
postalCode: z.string().min(1, "Postal code is required").max(20, "Postal code is too long").trim(),
|
|
country: z.string().min(1, "Country is required").max(100, "Country name is too long").trim(),
|
|
});
|
|
|
|
export const countryCodeSchema = z.string().length(2, "Country code must be 2 characters");
|
|
export const currencyCodeSchema = z.string().length(3, "Currency code must be 3 characters");
|
|
|
|
export const timestampSchema = z.string().datetime("Invalid timestamp format");
|
|
export const dateSchema = z.string().date("Invalid date format");
|
|
|
|
export const moneyAmountSchema = z.number().int().nonnegative("Amount must be non-negative");
|
|
export const percentageSchema = z.number().min(0).max(100, "Percentage must be between 0 and 100");
|
|
|
|
export const genderEnum = z.enum(["male", "female", "other"]);
|
|
export const statusEnum = z.enum(["active", "inactive", "pending", "suspended"]);
|
|
export const priorityEnum = z.enum(["low", "medium", "high", "urgent"]);
|
|
export const categoryEnum = z.enum(["technical", "billing", "account", "general"]);
|
|
|
|
export const billingCycleEnum = z.enum(["Monthly", "Quarterly", "Annually", "Onetime", "Free"]);
|
|
export const subscriptionBillingCycleEnum = z.enum([
|
|
"Monthly",
|
|
"Quarterly",
|
|
"Semi-Annually",
|
|
"Annually",
|
|
"Biennially",
|
|
"Triennially",
|
|
"One-time",
|
|
"Free",
|
|
]);
|