用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/RunnerQuan/SAFE-Agent --skill zod-3命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Find doctors with Healthgrades - search providers, read reviews, and check credentials
Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks.
基于RFM模型和回归算法的客户生命周期价值(LTV)预测分析工具,支持电商和零售业务的客户价值预测。使用时需要客户交易数据、订单历史或消费记录,自动进行RFM特征工程、回归建模和价值预测。
基于 SOC 职业分类
正在显示 SKILL.md
| name | zod-3 |
| description | Zod 3 validation schemas and patterns. Trigger: When creating Zod validation schemas for API input validation. |
| license | MIT |
| metadata | {"author":"migestion","version":"1.0","scope":["api"],"auto_invoke":"Creating Zod schemas"} |
| allowed-tools | Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task |
import { z } from 'zod';
export const createClientSchema = z.object({
companyName: z.string().min(1).max(100),
contactName: z.string().min(1).max(100),
email: z.string().email().optional().or(z.literal('')),
phone: z.string().optional().or(z.literal('')),
status: z.enum(['active', 'inactive', 'pending']),
segment: z.string().optional().or(z.literal('')),
tags: z.array(z.string()).optional(),
notes: z.string().optional().or(z.literal('')),
});
export type CreateClientInput = z.infer<typeof createClientSchema>;
z.string();
z.string().min(3); // Minimum length
z.string().max(100); // Maximum length
z.string().length(10); // Exact length
z.string().email(); // Email
z.string().url(); // URL
z.string().uuid(); // UUID
z.string().regex(/^[A-Z]/); // Regex
z.string().trim(); // Trim whitespace
z.string().optional(); // Optional
z.string().nullable(); // Nullable
z.string().default(''); // Default value
z.number();
z.number().min(0); // Minimum value
z.number().max(100); // Maximum value
z.number().int(); // Integer
z.number().positive(); // Positive
z.number().nonnegative(); // Non-negative
z.number().optional();
z.number().default(0);
z.boolean();
z.boolean().optional();
z.boolean().default(false);
z.enum(['active', 'inactive', 'pending']);
z.enum(['active', 'inactive']).default('active');
z.array(z.string()); // String array
z.array(z.string()).min(1); // Minimum items
z.array(z.string()).max(10); // Maximum items
z.array(z.string()).length(5); // Exact length
z.array(z.string()).optional();
z.array(z.string()).default([]);
z.object({
name: z.string(),
age: z.number().optional(),
});
z.object({}).strict(); // No extra fields allowed
z.object({}).passthrough(); // Allow extra fields
z.object({
user: z.object({
name: z.string(),
email: z.string().email(),
}),
});
z.string().optional(); // undefined allowed
z.string().nullable(); // null allowed
z.string().optional().nullable(); // both allowed
z.string().or(z.literal('')); // empty string allowed
z.string().default('default value');
z.number().default(0);
z.boolean().default(false);
z.array(z.string()).default([]);
z.string().refine(val => val.length >= 3, 'Must be at least 3 characters');
// With async validation
z.string().refine(async val => await isUniqueEmail(val), 'Email already exists');
// Transform before validation
z.string().transform(val => val.toLowerCase());
z.union([z.string(), z.number()]); // string OR number
z.discriminatedUnion('type', [
z.object({ type: z.literal('a'), value: z.string() }),
z.object({ type: z.literal('b'), value: z.number() }),
]);
z.literal('active');
z.literal(true);
z.literal(42);
z.array(z.literal('tag1', 'tag2', 'tag3'));
z.string().datetime(); // ISO datetime
z.string().date(); // YYYY-MM-DD
z.string().time(); // HH:mm:ss
z.string().uuid();
z.string().uuid().optional();
z.string().email();
z.string().email().optional().or(z.literal(''));
const passwordSchema = z
.string()
.min(8, 'Password must be at least 8 characters')
.regex(/[A-Z]/, 'Must contain uppercase letter')
.regex(/[a-z]/, 'Must contain lowercase letter')
.regex(/[0-9]/, 'Must contain number');
export const listClientsQuerySchema = z.object({
page: z.coerce.number().min(1).default(1),
limit: z.coerce.number().min(1).max(100).default(20),
search: z.string().optional(),
status: z.enum(['active', 'inactive', 'pending']).optional(),
sortBy: z.string().default('createdAt'),
sortOrder: z.enum(['asc', 'desc']).default('desc'),
});
export type ListClientsQuery = z.infer<typeof listClientsQuerySchema>;
export const validateBody = <T>(schema: z.ZodSchema<T>) => {
return (req: Request, res: Response, next: NextFunction) => {
const result = schema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({
success: false,
errors: result.error.errors,
});
}
req.body = result.data;
next();
};
};
// Usage
router.post('/clients', validateBody(createClientSchema), createHandler);
// Infer type from schema
type CreateClientInput = z.infer<typeof createClientSchema>;
// Parse and get typed result
const result = createClientSchema.parse(req.body);
// result is typed as CreateClientInput
// Safe parse (no throw)
const result = createClientSchema.safeParse(req.body);
if (result.success) {
const data = result.data;
} else {
console.log(result.error.errors);
}
{
"success": false,
"errors": [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": ["companyName"],
"message": "Required"
}
]
}
migestion-api - API validation patternstypescript - TypeScript patterns