Skip to main content
Glama
zod-schemas.ts3.73 kB
import { z } from "zod"; // ============================================ // Primitives // ============================================ const emailSchema = z.string().email().min(5).max(100).trim().toLowerCase(); const passwordSchema = z .string() .min(8, "Password must be at least 8 characters") .regex(/[A-Z]/, "Must contain at least one uppercase letter") .regex(/[a-z]/, "Must contain at least one lowercase letter") .regex(/[0-9]/, "Must contain at least one number") .regex(/[^A-Za-z0-9]/, "Must contain at least one special character"); const idSchema = z.string().uuid(); // ============================================ // Domain Schemas // ============================================ export const UserSchema = z.object({ id: idSchema, email: emailSchema, name: z.string().min(2).max(50), age: z.number().int().min(13).max(120).optional(), role: z.enum(["user", "admin", "moderator"]).default("user"), isActive: z.boolean().default(true), tags: z.array(z.string()).max(10), meta: z.record(z.unknown()).optional(), createdAt: z.date(), }); export const LoginRequestSchema = z.object({ email: emailSchema, password: z.string(), // Don't validate complexity on login, just type rememberMe: z.boolean().optional(), }); export const RegisterRequestSchema = z .object({ email: emailSchema, name: z.string().min(2), password: passwordSchema, confirmPassword: z.string(), }) .refine((data) => data.password === data.confirmPassword, { message: "Passwords don't match", path: ["confirmPassword"], }); // ============================================ // API Response Schemas // ============================================ export const ApiResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) => z.object({ success: z.boolean(), data: dataSchema.optional(), error: z .object({ code: z.string(), message: z.string(), details: z.any().optional(), }) .optional(), timestamp: z.string().datetime(), }); // ============================================ // Environment Validation // ============================================ export const EnvSchema = z.object({ NODE_ENV: z.enum(["development", "production", "test"]), PORT: z.coerce.number().default(3000), DATABASE_URL: z.string().url(), JWT_SECRET: z.string().min(32), API_KEY: z.string().optional(), }); // ============================================ // Utility Types (Inferred) // ============================================ export type User = z.infer<typeof UserSchema>; export type LoginRequest = z.infer<typeof LoginRequestSchema>; export type RegisterRequest = z.infer<typeof RegisterRequestSchema>; export type Env = z.infer<typeof EnvSchema>; // ============================================ // Error Handler Helper // ============================================ export const formatZodError = (error: z.ZodError) => { return error.errors.map((err) => ({ path: err.path.join("."), message: err.message, code: err.code, })); }; // ============================================ // Validation Middleware Example // ============================================ /* import { Request, Response, NextFunction } from 'express'; export const validate = (schema: z.ZodSchema) => (req: Request, res: Response, next: NextFunction) => { try { req.body = schema.parse(req.body); next(); } catch (error) { if (error instanceof z.ZodError) { return res.status(400).json({ success: false, errors: formatZodError(error) }); } next(error); } }; */

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server