2025-10-08 16:31:42 +09:00
|
|
|
/**
|
|
|
|
|
* Common Domain - Validation Utilities
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* Generic validation functions used across all domains.
|
|
|
|
|
* These are pure functions with no infrastructure dependencies.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { z } from "zod";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* UUID validation schema (v4)
|
|
|
|
|
*/
|
|
|
|
|
export const uuidSchema = z.string().uuid();
|
|
|
|
|
|
2025-10-08 16:50:51 +09:00
|
|
|
/**
|
|
|
|
|
* Required non-empty string schema (trimmed)
|
|
|
|
|
* Use for any string that must have a value
|
|
|
|
|
*/
|
|
|
|
|
export const requiredStringSchema = z.string().min(1, "This field is required").trim();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Customer number / account number schema
|
|
|
|
|
* Generic schema for customer/account identifiers
|
|
|
|
|
*/
|
|
|
|
|
export const customerNumberSchema = z.string().min(1, "Customer number is required").trim();
|
|
|
|
|
|
2025-10-08 16:31:42 +09:00
|
|
|
/**
|
|
|
|
|
* Normalize and validate an email address
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* This is a convenience wrapper that throws on invalid input.
|
|
|
|
|
* For validation without throwing, use the emailSchema directly with .safeParse()
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* @throws Error if email format is invalid
|
|
|
|
|
*/
|
|
|
|
|
export function normalizeAndValidateEmail(email: string): string {
|
2025-12-25 17:30:02 +09:00
|
|
|
const emailValidationSchema = z
|
|
|
|
|
.string()
|
|
|
|
|
.email()
|
|
|
|
|
.transform(e => e.toLowerCase().trim());
|
2025-10-08 16:31:42 +09:00
|
|
|
return emailValidationSchema.parse(email);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Validate a UUID (v4)
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* This is a convenience wrapper that throws on invalid input.
|
|
|
|
|
* For validation without throwing, use the uuidSchema directly with .safeParse()
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* @throws Error if UUID format is invalid
|
|
|
|
|
*/
|
2025-12-29 15:44:01 +09:00
|
|
|
export function validateUuidV4OrThrow(id: string, message = "Invalid UUID format"): string {
|
|
|
|
|
const parsed = uuidSchema.safeParse(id);
|
|
|
|
|
if (!parsed.success) {
|
|
|
|
|
throw new Error(message);
|
2025-10-08 16:31:42 +09:00
|
|
|
}
|
2025-12-29 15:44:01 +09:00
|
|
|
return parsed.data;
|
2025-10-08 16:31:42 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a string is a valid email (non-throwing)
|
|
|
|
|
*/
|
|
|
|
|
export function isValidEmail(email: string): boolean {
|
|
|
|
|
return z.string().email().safeParse(email).success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a string is a valid UUID (non-throwing)
|
|
|
|
|
*/
|
|
|
|
|
export function isValidUuid(id: string): boolean {
|
|
|
|
|
return uuidSchema.safeParse(id).success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* URL validation schema
|
|
|
|
|
*/
|
|
|
|
|
export const urlSchema = z.string().url();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Validate a URL
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* This is a convenience wrapper that throws on invalid input.
|
|
|
|
|
* For validation without throwing, use the urlSchema directly with .safeParse()
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* @throws Error if URL format is invalid
|
|
|
|
|
*/
|
|
|
|
|
export function validateUrlOrThrow(url: string): string {
|
|
|
|
|
try {
|
|
|
|
|
return urlSchema.parse(url);
|
|
|
|
|
} catch {
|
|
|
|
|
throw new Error("Invalid URL format");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Validate a URL (non-throwing)
|
2025-12-25 17:30:02 +09:00
|
|
|
*
|
2025-10-08 16:31:42 +09:00
|
|
|
* Returns validation result with errors if any.
|
|
|
|
|
* Prefer using urlSchema.safeParse() directly for more control.
|
|
|
|
|
*/
|
|
|
|
|
export function validateUrl(url: string): { isValid: boolean; errors: string[] } {
|
|
|
|
|
const result = urlSchema.safeParse(url);
|
|
|
|
|
return {
|
|
|
|
|
isValid: result.success,
|
|
|
|
|
errors: result.success ? [] : result.error.issues.map(i => i.message),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a string is a valid URL (non-throwing)
|
|
|
|
|
*/
|
|
|
|
|
export function isValidUrl(url: string): boolean {
|
|
|
|
|
return urlSchema.safeParse(url).success;
|
|
|
|
|
}
|