206 lines
5.4 KiB
TypeScript
206 lines
5.4 KiB
TypeScript
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<typeof configFormSchema>;
|
||
|
||
// 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
|
||
}
|
||
}
|
||
}; |