import { type ParseError } from 'inline-schema'; import type { Command, CommandSchema } from './types'; function validateCommandCore(command: Command, schema: CommandSchema): string[] { const errors: string[] = []; if (schema.name !== '' && command.name !== schema.name) { errors.push(`命令名称不匹配:期望 "${schema.name}",实际 "${command.name}"`); } const requiredParams = schema.params.filter(p => p.required); const variadicParam = schema.params.find(p => p.variadic); if (command.params.length < requiredParams.length) { errors.push(`参数不足:至少需要 ${requiredParams.length} 个参数,实际 ${command.params.length} 个`); } if (!variadicParam && command.params.length > schema.params.length) { errors.push(`参数过多:最多 ${schema.params.length} 个参数,实际 ${command.params.length} 个`); } const requiredOptions = Object.values(schema.options).filter(o => o.required); for (const opt of requiredOptions) { const hasOption = opt.name in command.options || (opt.short && opt.short in command.options); if (!hasOption) { errors.push(`缺少必需选项:--${opt.name}${opt.short ? ` 或 -${opt.short}` : ''}`); } } return errors; } export function applyCommandSchema( command: Command, schema: CommandSchema ): { command: Command; valid: true } | { command: Command; valid: false; errors: string[] } { const errors = validateCommandCore(command, schema); if (errors.length > 0) { return { command, valid: false, errors }; } const parseErrors: string[] = []; const parsedParams: unknown[] = [...command.params]; for (let i = 0; i < command.params.length; i++) { const paramValue = command.params[i]; const paramSchema = schema.params[i]?.schema; if (paramSchema && typeof paramValue === 'string') { try { parsedParams[i] = paramSchema.parse(paramValue); } catch (e) { const err = e as ParseError; parseErrors.push(`参数 "${schema.params[i]?.name}" 解析失败:${err.message}`); } } } const parsedOptions: Record = { ...command.options }; for (const [key, value] of Object.entries(command.options)) { const optSchema = schema.options[key] ?? (key.length === 1 ? Object.values(schema.options).find(o => o.short === key) : undefined); if (optSchema?.schema && typeof value === 'string') { try { parsedOptions[key] = optSchema.schema.parse(value); } catch (e) { const err = e as ParseError; parseErrors.push(`选项 "--${key}" 解析失败:${err.message}`); } } } const result = { ...command, params: parsedParams, options: parsedOptions }; if (parseErrors.length > 0) { return { command: result, valid: false, errors: parseErrors }; } return { command: result, valid: true }; }