Token导航 LogoToken导航TokenDH.com
前端设计需要联网github未标认证来源可访问clear审计通过

zod佐德

Agent Skill

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

总安装

247

周安装

10

GitHub Stars

11

下载量

78
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:zod(佐德)
来源仓库:https://github.com/oriolrius/pki-manager-web
仓库路径:skills/zod
安装命令:
npx skills add https://github.com/oriolrius/pki-manager-web --skill Zod
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/oriolrius/pki-manager-web --skill Zod

简介

用于辅助前端页面、组件和样式开发与维护。

  • 适合生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码。
  • 使用时需结合项目现有设计系统和构建方式,避免生成孤立片段。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装并使用。
  • 安装前建议确认权限范围和维护状态,注意是否会触发联网或文件读写操作。

SKILL.md

Zod

Expert assistance with Zod - TypeScript-first schema validation.

Overview

Zod is a TypeScript-first schema declaration and validation library:

  • Type Inference: Automatic TypeScript type inference
  • Zero Dependencies: No runtime dependencies
  • Composable: Build complex schemas from simple ones
  • Developer Experience: Excellent autocomplete and error messages

Installation

npm install zod

Basic Usage

import { z } from 'zod';

// Define schema
const userSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.string().email(),
});

// Infer TypeScript type
type User = z.infer<typeof userSchema>;
// type User = { name: string; age: number; email: string }

// Parse data (throws on validation error)
const user = userSchema.parse({
  name: 'John',
  age: 30,
  email: 'john@example.com',
});

// Safe parse (returns result object)
const result = userSchema.safeParse({ name: 'John', age: '30' });
if (result.success) {
  console.log(result.data);
} else {
  console.error(result.error);
}

Primitive Types

// String
z.string();
z.string().min(5);
z.string().max(100);
z.string().length(10);
z.string().email();
z.string().url();
z.string().uuid();
z.string().regex(/^[a-z]+$/);
z.string().startsWith('https://');
z.string().endsWith('.com');

// Number
z.number();
z.number().int();
z.number().positive();
z.number().negative();
z.number().min(0);
z.number().max(100);
z.number().multipleOf(5);

// Boolean
z.boolean();

// Date
z.date();
z.date().min(new Date('2024-01-01'));
z.date().max(new Date('2025-01-01'));

// Literal
z.literal('admin');
z.literal(42);
z.literal(true);

Complex Types

// Object
const userSchema = z.object({
  name: z.string(),
  age: z.number(),
});

// Array
z.array(z.string());
z.array(z.number()).min(1).max(10);

// Tuple
z.tuple([z.string(), z.number(), z.boolean()]);

// Union (OR)
z.union([z.string(), z.number()]);
z.string().or(z.number()); // Same as above

// Discriminated Union
const shapeSchema = z.discriminatedUnion('kind', [
  z.object({ kind: z.literal('circle'), radius: z.number() }),
  z.object({ kind: z.literal('rectangle'), width: z.number(), height: z.number() }),
]);

// Intersection (AND)
const baseUser = z.object({ id: z.string() });
const namedUser = z.object({ name: z.string() });
const user = z.intersection(baseUser, namedUser);
// Or use extend
const user = baseUser.extend({ name: z.string() });

// Enum
z.enum(['admin', 'user', 'guest']);
z.nativeEnum(MyEnum);

// Record
z.record(z.string()); // { [key: string]: string }
z.record(z.string(), z.number()); // { [key: string]: number }

// Map
z.map(z.string(), z.number());

// Set
z.set(z.string());

Modifiers

// Optional
z.string().optional(); // string | undefined
z.object({ name: z.string().optional() });

// Nullable
z.string().nullable(); // string | null

// Nullish (optional + nullable)
z.string().nullish(); // string | null | undefined

// Default
z.string().default('default value');
z.number().default(0);

// Catch (provide fallback on parse error)
z.string().catch('fallback');

Refinements

// Custom validation
const passwordSchema = z.string().refine(
  (val) => val.length >= 8,
  { message: 'Password must be at least 8 characters' }
);

// Multiple refinements
const schema = z.string()
  .min(8)
  .refine((val) => /[A-Z]/.test(val), {
    message: 'Must contain uppercase letter',
  })
  .refine((val) => /[0-9]/.test(val), {
    message: 'Must contain number',
  });

// Superrefine (access ctx for multiple errors)
const schema = z.string().superRefine((val, ctx) => {
  if (val.length < 8) {
    ctx.addIssue({
      code: z.ZodIssueCode.too_small,
      minimum: 8,
      type: 'string',
      inclusive: true,
      message: 'Too short',
    });
  }
  if (!/[A-Z]/.test(val)) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: 'Must contain uppercase',
    });
  }
});

Transformations

// Transform value
const schema = z.string().transform((val) => val.toLowerCase());

// Chain transforms
const schema = z.string()
  .transform((val) => val.trim())
  .transform((val) => val.toLowerCase());

// Transform to different type
const numberSchema = z.string().transform((val) => parseInt(val, 10));

// Preprocess before validation
const schema = z.preprocess(
  (val) => (typeof val === 'string' ? val.trim() : val),
  z.string().min(1)
);

Object Methods

const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string(),
  age: z.number(),
});

// Pick fields
const nameOnly = userSchema.pick({ name: true });

// Omit fields
const withoutId = userSchema.omit({ id: true });

// Partial (all fields optional)
const partialUser = userSchema.partial();

// Deep Partial
const deepPartial = userSchema.deepPartial();

// Required (make all fields required)
const required = partialUser.required();

// Extend
const extendedUser = userSchema.extend({
  role: z.enum(['admin', 'user']),
});

// Merge
const merged = userSchema.merge(z.object({ role: z.string() }));

// Passthrough (allow extra fields)
const schema = userSchema.passthrough();

// Strict (disallow extra fields)
const schema = userSchema.strict();

// Strip (remove extra fields, default)
const schema = userSchema.strip();

Error Handling

const schema = z.object({
  name: z.string().min(2),
  age: z.number().min(18),
});

const result = schema.safeParse({ name: 'J', age: 15 });

if (!result.success) {
  // Zod error object
  console.log(result.error);

  // Format errors
  console.log(result.error.format());
  /*
  {
    name: { _errors: ['String must contain at least 2 characters'] },
    age: { _errors: ['Number must be greater than or equal to 18'] }
  }
  */

  // Flatten errors
  console.log(result.error.flatten());
  /*
  {
    formErrors: [],
    fieldErrors: {
      name: ['String must contain at least 2 characters'],
      age: ['Number must be greater than or equal to 18']
    }
  }
  */

  // Get first error
  console.log(result.error.issues[0]);
}

// Custom error messages
const schema = z.string().min(5, { message: 'Too short!' });
const schema = z.string().email({ message: 'Invalid email address' });

// Custom error map
const schema = z.string().min(5, 'Custom error');

Async Validation

// Async refinement
const schema = z.string().refine(
  async (email) => {
    const exists = await checkEmailExists(email);
    return !exists;
  },
  { message: 'Email already exists' }
);

// Parse async
const result = await schema.parseAsync('test@example.com');
const result = await schema.safeParseAsync('test@example.com');

React Hook Form Integration

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

const formSchema = z.object({
  name: z.string().min(2, 'Name must be at least 2 characters'),
  email: z.string().email('Invalid email address'),
  age: z.number().min(18, 'Must be 18 or older'),
});

type FormData = z.infer<typeof formSchema>;

function MyForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(formSchema),
  });

  const onSubmit = (data: FormData) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} />
      {errors.name && <span>{errors.name.message}</span>}

      <input {...register('email')} />
      {errors.email && <span>{errors.email.message}</span>}

      <input {...register('age', { valueAsNumber: true })} type="number" />
      {errors.age && <span>{errors.age.message}</span>}

      <button type="submit">Submit</button>
    </form>
  );
}

tRPC Integration

import { z } from 'zod';
import { publicProcedure, router } from './trpc';

const createUserSchema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
});

export const userRouter = router({
  create: publicProcedure
    .input(createUserSchema)
    .mutation(({ input }) => {
      // input is fully typed!
      const { name, email } = input;
      return createUser({ name, email });
    }),
});

Common Patterns

PKI Certificate Validation

const distinguishedNameSchema = z.object({
  commonName: z.string().min(1),
  organization: z.string().optional(),
  organizationalUnit: z.string().optional(),
  country: z.string().length(2).optional(),
  state: z.string().optional(),
  locality: z.string().optional(),
});

const certificateSchema = z.object({
  subject: distinguishedNameSchema,
  issuer: distinguishedNameSchema,
  serialNumber: z.string(),
  notBefore: z.date(),
  notAfter: z.date(),
  keyUsage: z.array(z.enum([
    'digitalSignature',
    'nonRepudiation',
    'keyEncipherment',
    'dataEncipherment',
    'keyAgreement',
    'keyCertSign',
    'cRLSign',
  ])),
  extendedKeyUsage: z.array(z.enum([
    'serverAuth',
    'clientAuth',
    'codeSigning',
    'emailProtection',
    'timeStamping',
    'OCSPSigning',
  ])).optional(),
  subjectAlternativeNames: z.array(z.string()).optional(),
}).refine(
  (data) => data.notAfter > data.notBefore,
  { message: 'notAfter must be after notBefore' }
);

API Response Validation

const apiResponseSchema = z.object({
  success: z.boolean(),
  data: z.unknown().optional(),
  error: z.object({
    code: z.string(),
    message: z.string(),
  }).optional(),
}).refine(
  (data) => data.success ? data.data !== undefined : data.error !== undefined,
  { message: 'Response must have data if success, or error if not' }
);

Best Practices

  1. Type Inference: Always use z.infer<typeof schema> for types
  2. Reusable Schemas: Define common schemas once, reuse everywhere
  3. Composition: Build complex schemas from simple ones
  4. Error Messages: Provide clear custom error messages
  5. safeParse: Use safeParse when you want to handle errors yourself
  6. Transformations: Use transforms to normalize data
  7. Refinements: Use refinements for complex business logic
  8. Optional vs Nullable: Understand the difference
  9. Strict Mode: Use .strict() on objects to catch extra fields
  10. Documentation: Add JSDoc comments to schemas

Resources

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Cursor

30.37%
按下载量换算24

OpenCode

24.34%
按下载量换算19

Codex

18.31%
按下载量换算14

Claude Code

12.79%
按下载量换算10

windsurf

7.83%
按下载量换算6

trae

3.39%
按下载量换算3

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills