mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 07:51:13 -05:00
126 lines
3.1 KiB
TypeScript
126 lines
3.1 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
/**
|
|
* Admin form validation schemas
|
|
* Provides type-safe validation for admin settings and user management forms
|
|
*/
|
|
|
|
/**
|
|
* Email validation schema
|
|
* Ensures valid email format with reasonable length constraints
|
|
*/
|
|
export const emailSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(1, 'Email is required')
|
|
.max(255, 'Email must be less than 255 characters')
|
|
.email('Invalid email address')
|
|
.toLowerCase();
|
|
|
|
/**
|
|
* URL validation schema
|
|
* Validates URLs with http/https protocol and reasonable length
|
|
*/
|
|
export const urlSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(1, 'URL is required')
|
|
.max(2048, 'URL must be less than 2048 characters')
|
|
.url('Invalid URL format')
|
|
.refine(
|
|
(url) => url.startsWith('http://') || url.startsWith('https://'),
|
|
'URL must start with http:// or https://'
|
|
);
|
|
|
|
/**
|
|
* Username validation schema
|
|
* Alphanumeric with underscores and hyphens, 3-30 characters
|
|
*/
|
|
export const usernameSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(3, 'Username must be at least 3 characters')
|
|
.max(30, 'Username must be less than 30 characters')
|
|
.regex(
|
|
/^[a-zA-Z0-9_-]+$/,
|
|
'Username can only contain letters, numbers, underscores, and hyphens'
|
|
);
|
|
|
|
/**
|
|
* Display name validation schema
|
|
* More permissive than username, allows spaces and special characters
|
|
*/
|
|
export const displayNameSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(1, 'Display name is required')
|
|
.max(100, 'Display name must be less than 100 characters');
|
|
|
|
/**
|
|
* Admin settings validation schema
|
|
* For system-wide configuration values
|
|
*/
|
|
export const adminSettingsSchema = z.object({
|
|
email: emailSchema.optional(),
|
|
url: urlSchema.optional(),
|
|
username: usernameSchema.optional(),
|
|
displayName: displayNameSchema.optional(),
|
|
});
|
|
|
|
/**
|
|
* User search validation schema
|
|
* For searching users in admin panel
|
|
*/
|
|
export const userSearchSchema = z.object({
|
|
query: z
|
|
.string()
|
|
.trim()
|
|
.min(1, 'Search query must be at least 1 character')
|
|
.max(100, 'Search query must be less than 100 characters'),
|
|
});
|
|
|
|
/**
|
|
* Helper function to validate email
|
|
*/
|
|
export function validateEmail(email: string): { valid: boolean; error?: string } {
|
|
try {
|
|
emailSchema.parse(email);
|
|
return { valid: true };
|
|
} catch (error: unknown) {
|
|
if (error instanceof z.ZodError) {
|
|
return { valid: false, error: error.issues[0]?.message };
|
|
}
|
|
return { valid: false, error: 'Invalid email' };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper function to validate URL
|
|
*/
|
|
export function validateUrl(url: string): { valid: boolean; error?: string } {
|
|
try {
|
|
urlSchema.parse(url);
|
|
return { valid: true };
|
|
} catch (error: unknown) {
|
|
if (error instanceof z.ZodError) {
|
|
return { valid: false, error: error.issues[0]?.message };
|
|
}
|
|
return { valid: false, error: 'Invalid URL' };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper function to validate username
|
|
*/
|
|
export function validateUsername(username: string): { valid: boolean; error?: string } {
|
|
try {
|
|
usernameSchema.parse(username);
|
|
return { valid: true };
|
|
} catch (error: unknown) {
|
|
if (error instanceof z.ZodError) {
|
|
return { valid: false, error: error.issues[0]?.message };
|
|
}
|
|
return { valid: false, error: 'Invalid username' };
|
|
}
|
|
}
|