import { z } from "zod"; export const configFormSchema = z.object({ 'site.name': z.string(), 'site.description': z.string(), 'site.keywords': z.string(), 'site.url': z.string() .refine((url) => { if (!url || url === "") return true; // 允许空值 return url.startsWith("http://") || url.startsWith("https://"); }, "无效的URL格式,必须以http://或https://开头"), 'site.logo': z.string(), 'site.copyright': z.string(), 'site.icp': z.string(), 'site.icp_url': z.string(), 'site.color_style': z.string(), 'user.default_avatar': z.string(), 'user.default_role': z.string(), 'user.register_invite_code': z.boolean(), 'user.register_email_verification': z.boolean(), 'user.open_login': z.boolean(), 'user.open_reset_password': z.boolean(), 'email.smtp_host': z.string(), 'email.smtp_port': z.number().int().min(1).max(65535), 'email.smtp_user': z.string(), 'email.smtp_password': z.string(), 'email.smtp_from': z.string(), 'email.smtp_from_name': z.string(), 'email.smtp_from_email': z.string() .refine((email) => { if (!email || email === "") return true; // 允许空值 return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); }, "无效的邮箱格式"), 'email.system_template': z.string(), 'blog.default_author': z.string(), 'blog.default_category': z.string(), 'blog.default_tag': z.string(), 'blog.open_comment': z.boolean(), 'logging.level': z.enum(["trace", "debug", "info", "warn", "error"], { message: "日志级别必须是以下之一: trace, debug, info, warn, error" }), 'logging.max_files': z.number().int().min(1).max(1000), 'logging.max_file_size': z.number().int().min(1).max(10240), 'cache.ttl': z.number().int().min(1).max(31536000), 'cache.max_size': z.number().int().min(1).max(1048576), 'switch.open_register': z.boolean(), 'switch.open_login': z.boolean(), 'switch.open_reset_password': z.boolean(), 'switch.open_comment': z.boolean(), 'switch.open_like': z.boolean(), 'switch.open_share': z.boolean(), 'switch.open_view': z.boolean(), }) export type ConfigFormValues = z.infer; // GraphQL UpdateConfig 输入类型 export interface UpdateConfig { key: string; value: string; // GraphQL schema 要求所有值都是字符串 description?: string; category?: string; is_editable?: boolean; } // Config interface for component use export interface Config { app: { name: string; version: string; debug: boolean; timezone: string; }; database: { max_connections: number; connection_timeout: number; }; kafka: { max_retries: number; retry_delay: number; }; security: { session_timeout: number; max_login_attempts: number; }; logging: { level: string; max_files: number; }; cache: { ttl: number; max_size: number; }; site: { name: string; locale_default: string; brand: { logo_url: string; primary_color: string; dark_mode_default: boolean; }; }; notice: { banner: { enabled: boolean; text: { 'zh-CN': string; 'en': string; }; }; }; maintenance: { window: { enabled: boolean; start_time: string; end_time: string; message: { 'zh-CN': string; 'en': string; }; }; }; ops: { features: { registration_enabled: boolean; invite_code_required: boolean; email_verification: boolean; }; limits: { max_users: number; max_invite_codes_per_user: number; session_timeout_hours: number; }; }; } // Default configuration export const defaultConfig: Config = { app: { name: "MosaicMap", version: "1.0.0", debug: false, timezone: "Asia/Shanghai" }, database: { max_connections: 100, connection_timeout: 30 }, kafka: { max_retries: 3, retry_delay: 1000 }, security: { session_timeout: 3600, max_login_attempts: 5 }, logging: { level: "info", max_files: 10 }, cache: { ttl: 3600, max_size: 1000 }, site: { name: "MosaicMap", locale_default: "zh-CN", brand: { logo_url: "", primary_color: "#3b82f6", dark_mode_default: false } }, notice: { banner: { enabled: false, text: { 'zh-CN': '', 'en': '' } } }, maintenance: { window: { enabled: false, start_time: '', end_time: '', message: { 'zh-CN': '', 'en': '' } } }, ops: { features: { registration_enabled: true, invite_code_required: false, email_verification: false }, limits: { max_users: 10000, max_invite_codes_per_user: 10, session_timeout_hours: 24 } } };