Merge pull request #207 from sx4im/add-skill-zod-validation-expert

feat(skills): add zod-validation-expert skill for type-safe schema definitions and parsing
This commit is contained in:
sickn33
2026-03-06 08:43:20 +01:00
committed by GitHub
6 changed files with 311 additions and 7 deletions

View File

@@ -2,7 +2,7 @@
Generated at: 2026-02-08T00:00:00.000Z
Total skills: 1006
Total skills: 1007
## architecture (69)
@@ -325,7 +325,7 @@ applications. | php | php, pro, write, idiomatic, code, generators, iterators, s
| `xlsx-official` | Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work ... | xlsx, official | xlsx, official, spreadsheet, creation, editing, analysis, formulas, formatting, data, visualization, claude, work |
| `youtube-automation` | Automate YouTube tasks via Rube MCP (Composio): upload videos, manage playlists, search content, get analytics, and handle comments. Always search tools firs... | youtube | youtube, automation, automate, tasks, via, rube, mcp, composio, upload, videos, playlists, search |
## development (150)
## development (151)
| Skill | Description | Tags | Triggers |
| --- | --- | --- | --- |
@@ -478,6 +478,7 @@ applications. | php | php, pro, write, idiomatic, code, generators, iterators, s
| `uv-package-manager` | Master the uv package manager for fast Python dependency management, virtual environments, and modern Python project workflows. Use when setting up Python pr... | uv, package, manager | uv, package, manager, fast, python, dependency, virtual, environments, setting, up, managing, dependencies |
| `viral-generator-builder` | Expert in building shareable generator tools that go viral - name generators, quiz makers, avatar creators, personality tests, and calculator tools. Covers t... | viral, generator, builder | viral, generator, builder, building, shareable, go, name, generators, quiz, makers, avatar, creators |
| `webapp-testing` | Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing... | webapp | webapp, testing, toolkit, interacting, local, web, applications, playwright, supports, verifying, frontend, functionality |
| `zod-validation-expert` | Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js... | zod, validation | zod, validation, typescript, first, schema, covers, parsing, custom, errors, refinements, type, inference |
| `zustand-store-ts` | Create Zustand stores with TypeScript, subscribeWithSelector middleware, and proper state/action separation. Use when building React state management, creati... | zustand, store, ts | zustand, store, ts, stores, typescript, subscribewithselector, middleware, proper, state, action, separation, building |
## general (200)

View File

@@ -1,6 +1,6 @@
# 🌌 Antigravity Awesome Skills: 1006+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
# 🌌 Antigravity Awesome Skills: 1007+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More
> **The Ultimate Collection of 1006+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL**
> **The Ultimate Collection of 1007+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL**
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Claude Code](https://img.shields.io/badge/Claude%20Code-Anthropic-purple)](https://claude.ai)
@@ -42,7 +42,7 @@ This repository provides essential skills to transform your AI assistant into a
- [🎁 Curated Collections (Bundles)](#curated-collections)
- [🧭 Antigravity Workflows](#antigravity-workflows)
- [📦 Features & Categories](#features--categories)
- [📚 Browse 1006+ Skills](#browse-1006-skills)
- [📚 Browse 1007+ Skills](#browse-1007-skills)
- [🤝 How to Contribute](#how-to-contribute)
- [💬 Community](#community)
- [☕ Support the Project](#support-the-project)
@@ -341,7 +341,7 @@ The repository is organized into specialized domains to transform your AI into a
Counts change as new skills are added. For the current full registry, see [CATALOG.md](CATALOG.md).
## Browse 1006+ Skills
## Browse 1007+ Skills
We have moved the full skill registry to a dedicated catalog to keep this README clean, and we've also introduced an interactive **Web App**!

View File

@@ -251,6 +251,7 @@
"web-artifacts-builder",
"webapp-testing",
"wordpress-plugin-development",
"zod-validation-expert",
"zustand-store-ts"
]
},

View File

@@ -1,6 +1,6 @@
{
"generatedAt": "2026-02-08T00:00:00.000Z",
"total": 1006,
"total": 1007,
"skills": [
{
"id": "00-andruia-consultant",
@@ -24688,6 +24688,31 @@
],
"path": "skills/zendesk-automation/SKILL.md"
},
{
"id": "zod-validation-expert",
"name": "zod-validation-expert",
"description": "Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.",
"category": "development",
"tags": [
"zod",
"validation"
],
"triggers": [
"zod",
"validation",
"typescript",
"first",
"schema",
"covers",
"parsing",
"custom",
"errors",
"refinements",
"type",
"inference"
],
"path": "skills/zod-validation-expert/SKILL.md"
},
{
"id": "zoho-crm-automation",
"name": "zoho-crm-automation",

View File

@@ -0,0 +1,267 @@
---
name: zod-validation-expert
description: "Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC."
risk: safe
source: community
date_added: "2026-03-05"
---
# Zod Validation Expert
You are a production-grade Zod expert. You help developers build type-safe schema definitions and validation logic. You master Zod fundamentals (primitives, objects, arrays, records), type inference (`z.infer`), complex validations (`.refine`, `.superRefine`), transformations (`.transform`), and integrations across the modern TypeScript ecosystem (React Hook Form, Next.js API Routes / App Router Actions, tRPC, and environment variables).
## When to Use This Skill
- Use when defining TypeScript validation schemas for API inputs or forms
- Use when setting up environment variable validation (`process.env`)
- Use when integrating Zod with React Hook Form (`@hookform/resolvers/zod`)
- Use when extracting or inferring TypeScript types from runtime validation schemas
- Use when writing complex validation rules (e.g., cross-field validation, async validation)
- Use when transforming input data (e.g., string to Date, string to number coercion)
- Use when standardizing error message formatting
## Core Concepts
### Why Zod?
Zod eliminates the duplication of writing a TypeScript interface *and* a runtime validation schema. You define the schema once, and Zod infers the static TypeScript type. Note that Zod is for **parsing, not just validation**. `safeParse` and `parse` return clean, typed data, stripping out unknown keys by default.
## Schema Definition & Inference
### Primitives & Coercion
```typescript
import { z } from "zod";
// Basic primitives
const stringSchema = z.string().min(3).max(255);
const numberSchema = z.number().int().positive();
const dateSchema = z.date();
// Coercion (automatically casting inputs before validation)
// Highly useful for FormData in Next.js Server Actions or URL queries
const ageSchema = z.coerce.number().min(18); // "18" -> 18
const activeSchema = z.coerce.boolean(); // "true" -> true
const dobSchema = z.coerce.date(); // "2020-01-01" -> Date object
```
### Objects & Type Inference
```typescript
const UserSchema = z.object({
id: z.string().uuid(),
username: z.string().min(3).max(20),
email: z.string().email(),
role: z.enum(["ADMIN", "USER", "GUEST"]).default("USER"),
age: z.number().min(18).optional(), // Can be omitted
website: z.string().url().nullable(), // Can be null
tags: z.array(z.string()).min(1), // Array with at least 1 item
});
// Infer the TypeScript type directly from the schema
// No need to write a separate `interface User { ... }`
export type User = z.infer<typeof UserSchema>;
```
### Advanced Types
```typescript
// Records (Objects with dynamic keys but specific value types)
const envSchema = z.record(z.string(), z.string()); // Record<string, string>
// Unions (OR)
const idSchema = z.union([z.string(), z.number()]); // string | number
// Or simpler:
const idSchema2 = z.string().or(z.number());
// Discriminated Unions (Type-safe switch cases)
const ActionSchema = z.discriminatedUnion("type", [
z.object({ type: z.literal("create"), id: z.string() }),
z.object({ type: z.literal("update"), id: z.string(), data: z.any() }),
z.object({ type: z.literal("delete"), id: z.string() }),
]);
```
## Parsing & Validation
### parse vs safeParse
```typescript
const schema = z.string().email();
// ❌ parse: Throws a ZodError if validation fails
try {
const email = schema.parse("invalid-email");
} catch (err) {
if (err instanceof z.ZodError) {
console.error(err.issues);
}
}
// ✅ safeParse: Returns a result object (No try/catch needed)
const result = schema.safeParse("user@example.com");
if (!result.success) {
// TypeScript narrows result to SafeParseError
console.log(result.error.format());
// Early return or throw domain error
} else {
// TypeScript narrows result to SafeParseSuccess
const validEmail = result.data; // Type is `string`
}
```
## Customizing Validation
### Custom Error Messages
```typescript
const passwordSchema = z.string()
.min(8, { message: "Password must be at least 8 characters long" })
.max(100, { message: "Password is too long" })
.regex(/[A-Z]/, { message: "Password must contain at least one uppercase letter" })
.regex(/[0-9]/, { message: "Password must contain at least one number" });
// Global custom error map (useful for i18n)
z.setErrorMap((issue, ctx) => {
if (issue.code === z.ZodIssueCode.invalid_type) {
if (issue.expected === "string") return { message: "This field must be text" };
}
return { message: ctx.defaultError };
});
```
### Refinements (Custom Logic)
```typescript
// Basic refinement
const passwordCheck = z.string().refine((val) => val !== "password123", {
message: "Password is too weak",
});
// Cross-field validation (e.g., password matching)
const formSchema = z.object({
password: z.string().min(8),
confirmPassword: z.string()
}).refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"], // Sets the error on the specific field
});
```
### Transformations
```typescript
// Change data during parsing
const stringToNumber = z.string()
.transform((val) => parseInt(val, 10))
.refine((val) => !isNaN(val), { message: "Not a valid integer" });
// Now the inferred type is `number`, not `string`!
type TransformedResult = z.infer<typeof stringToNumber>; // number
```
## Integration Patterns
### React Hook Form
```typescript
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const loginSchema = z.object({
email: z.string().email("Invalid email address"),
password: z.string().min(6, "Password must be 6+ characters"),
});
type LoginFormValues = z.infer<typeof loginSchema>;
export function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<LoginFormValues>({
resolver: zodResolver(loginSchema)
});
const onSubmit = (data: LoginFormValues) => {
// data is fully typed and validated
console.log(data.email, data.password);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <span>{errors.email.message}</span>}
{/* ... */}
</form>
);
}
```
### Next.js Server Actions
```typescript
"use server";
import { z } from "zod";
// Coercion is critical here because FormData values are always strings
const createPostSchema = z.object({
title: z.string().min(3),
content: z.string().optional(),
published: z.coerce.boolean().default(false), // checkbox -> "on" -> true
});
export async function createPost(prevState: any, formData: FormData) {
// Convert FormData to standard object using Object.fromEntries
const rawData = Object.fromEntries(formData.entries());
const validatedFields = createPostSchema.safeParse(rawData);
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
};
}
// Proceed with validated database operation
const { title, content, published } = validatedFields.data;
// ...
return { success: true };
}
```
### Environment Variables
```typescript
// Make environment variables strictly typed and fail-fast
import { z } from "zod";
const envSchema = z.object({
DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
PORT: z.coerce.number().default(3000),
API_KEY: z.string().min(10),
});
// Fails the build immediately if env vars are missing or invalid
const env = envSchema.parse(process.env);
export default env;
```
## Best Practices
-**Do:** Co-locate schemas alongside the components or API routes that use them to maintain separation of concerns.
-**Do:** Use `z.infer<typeof Schema>` everywhere instead of maintaining duplicate TypeScript interfaces manually.
-**Do:** Prefer `safeParse` over `parse` to avoid scattered `try/catch` blocks and leverage TypeScript's control flow narrowing for robust error handling.
-**Do:** Use `z.coerce` when accepting data from `URLSearchParams` or `FormData`, and be aware that `z.coerce.boolean()` converts standard `"false"`/`"off"` strings unexpectedly without custom preprocessing.
-**Do:** Use `.flatten()` or `.format()` on `ZodError` objects to easily extract serializable, human-readable errors for frontend consumption.
-**Don't:** Rely exclusively on `.partial()` for update schemas if field types or constraints differ between creation and update operations; define distinct schemas instead.
-**Don't:** Forget to pass the `path` option in `.refine()` or `.superRefine()` when performing object-level cross-field validations, otherwise the error won't attach to the correct input field.
## Troubleshooting
**Problem:** `Type instantiation is excessively deep and possibly infinite.`
**Solution:** This occurs with extreme schema recursion (e.g. deeply nested self-referential schemas). Use `z.lazy(() => NodeSchema)` for recursive structures and define the base TypeScript type explicitly instead of solely inferring it.
**Problem:** Empty strings pass validation when using `.optional()`.
**Solution:** `.optional()` permits `undefined`, not empty strings. If an empty string means "no value," use `.or(z.literal(""))` or preprocess it: `z.string().transform(v => v === "" ? undefined : v).optional()`.

View File

@@ -10029,6 +10029,16 @@
"source": "community",
"date_added": "2026-02-27"
},
{
"id": "zod-validation-expert",
"path": "skills/zod-validation-expert",
"category": "uncategorized",
"name": "zod-validation-expert",
"description": "Expert in Zod \u2014 TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.",
"risk": "safe",
"source": "community",
"date_added": "2026-03-05"
},
{
"id": "zoho-crm-automation",
"path": "skills/zoho-crm-automation",