name: argument-validator-generator description: 为CLI应用程序生成包含类型强制转换、约束检查、自定义验证器和有用错误消息的参数验证逻辑。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep
参数验证器生成器
为CLI应用程序生成全面的参数验证逻辑,包含类型强制转换和约束检查。
功能
- 为参数生成类型强制转换函数
- 创建带有约束检查的自定义验证器
- 设置验证错误消息
- 实现值规范化
- 配置互斥验证
- 生成验证模式
使用场景
在以下情况下调用此技能:
- 为CLI参数添加类型验证
- 创建自定义参数验证器
- 实现复杂的约束检查
- 生成有用的验证错误消息
输入参数
| 参数 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
| language | string | 是 | 目标语言(typescript, python, go, rust) |
| validators | array | 是 | 要生成的验证器列表 |
| outputPath | string | 否 | 生成文件的输出路径 |
验证器结构
{
"validators": [
{
"name": "port",
"type": "number",
"constraints": {
"min": 1,
"max": 65535
},
"errorMessage": "端口号必须在1到65535之间"
},
{
"name": "email",
"type": "string",
"pattern": "^[\\w.-]+@[\\w.-]+\\.\\w+$",
"errorMessage": "邮箱格式无效"
},
{
"name": "environment",
"type": "enum",
"values": ["development", "staging", "production"],
"aliases": { "dev": "development", "prod": "production" }
}
]
}
生成的代码模式
TypeScript验证器
import { z } from 'zod';
// 端口验证器
export const portSchema = z
.number()
.int()
.min(1, '端口号必须至少为1')
.max(65535, '端口号最多为65535');
export function validatePort(value: unknown): number {
const parsed = typeof value === 'string' ? parseInt(value, 10) : value;
return portSchema.parse(parsed);
}
// 邮箱验证器
export const emailSchema = z
.string()
.email('邮箱格式无效')
.toLowerCase();
export function validateEmail(value: unknown): string {
return emailSchema.parse(value);
}
// 环境枚举验证器(含别名)
const envAliases: Record<string, string> = {
dev: 'development',
prod: 'production',
};
export const environmentSchema = z
.string()
.transform((val) => envAliases[val] || val)
.pipe(z.enum(['development', 'staging', 'production']));
export function validateEnvironment(value: unknown): string {
return environmentSchema.parse(value);
}
Python验证器
from typing import Any, List, Optional, Union
import re
class ValidationError(Exception):
"""验证失败时抛出。"""
pass
def validate_port(value: Any) -> int:
"""验证端口号。"""
try:
port = int(value)
except (TypeError, ValueError):
raise ValidationError(f"无效的端口号: {value}")
if not 1 <= port <= 65535:
raise ValidationError("端口号必须在1到65535之间")
return port
def validate_email(value: Any) -> str:
"""验证邮箱地址。"""
if not isinstance(value, str):
raise ValidationError(f"邮箱必须是字符串,但得到的是 {type(value).__name__}")
pattern = r'^[\w.-]+@[\w.-]+\.\w+$'
if not re.match(pattern, value):
raise ValidationError("邮箱格式无效")
return value.lower()
ENV_ALIASES = {'dev': 'development', 'prod': 'production'}
VALID_ENVIRONMENTS = ['development', 'staging', 'production']
def validate_environment(value: Any) -> str:
"""验证环境名称。"""
if not isinstance(value, str):
raise ValidationError(f"环境必须是字符串")
normalized = ENV_ALIASES.get(value, value)
if normalized not in VALID_ENVIRONMENTS:
raise ValidationError(
f"无效的环境: {value}。"
f"必须是以下之一: {', '.join(VALID_ENVIRONMENTS)}"
)
return normalized
Go验证器
package validators
import (
"fmt"
"regexp"
"strconv"
"strings"
)
// ValidationError 表示验证失败
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
// ValidatePort 验证端口号
func ValidatePort(value string) (int, error) {
port, err := strconv.Atoi(value)
if err != nil {
return 0, &ValidationError{
Field: "port",
Message: fmt.Sprintf("无效的端口号: %s", value),
}
}
if port < 1 || port > 65535 {
return 0, &ValidationError{
Field: "port",
Message: "端口号必须在1到65535之间",
}
}
return port, nil
}
// ValidateEmail 验证邮箱地址
func ValidateEmail(value string) (string, error) {
pattern := `^[\w.-]+@[\w.-]+\.\w+$`
matched, _ := regexp.MatchString(pattern, value)
if !matched {
return "", &ValidationError{
Field: "email",
Message: "邮箱格式无效",
}
}
return strings.ToLower(value), nil
}
var envAliases = map[string]string{
"dev": "development",
"prod": "production",
}
var validEnvironments = []string{"development", "staging", "production"}
// ValidateEnvironment 验证环境名称
func ValidateEnvironment(value string) (string, error) {
if alias, ok := envAliases[value]; ok {
value = alias
}
for _, env := range validEnvironments {
if env == value {
return value, nil
}
}
return "", &ValidationError{
Field: "environment",
Message: fmt.Sprintf("无效的环境: %s", value),
}
}
验证模式
复合验证器
// 带有特定协议的URL验证
export const apiUrlSchema = z
.string()
.url()
.refine(
(url) => url.startsWith('https://'),
'API URL必须使用HTTPS'
);
// 必须存在的文件路径验证
export const existingFileSchema = z
.string()
.refine(
(path) => fs.existsSync(path),
(path) => ({ message: `文件未找到: ${path}` })
);
依赖验证
// 验证结束日期在开始日期之后
export const dateRangeSchema = z.object({
startDate: z.coerce.date(),
endDate: z.coerce.date(),
}).refine(
(data) => data.endDate > data.startDate,
'结束日期必须在开始日期之后'
);
工作流程
- 分析需求 - 审查验证需求
- 生成基础验证器 - 类型强制转换和基本检查
- 添加约束 - 最小值/最大值、模式、枚举
- 创建错误消息 - 有用、可操作的消息
- 添加别名/转换 - 规范化输入值
- 生成测试 - 验证测试用例
应用的最佳实践
- 验证前进行类型强制转换
- 描述性错误消息
- 输入规范化(小写、修剪)
- 支持常见值的别名
- 可组合的验证模式
- 一致的错误类型
目标流程
- 参数解析器设置
- 错误处理与用户反馈
- CLI命令结构设计