Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 63x 63x 63x 63x 63x 63x 63x 63x 22x 21x 21x 28x 28x 28x 28x 28x 21x 21x 21x 1x 1x 63x | import { z } from "zod";
/**
* Validation schemas for API endpoints
* All schemas use Zod for runtime validation
*/
// ============================================================================
// PRODUCT SCHEMAS
// ============================================================================
export const createProductSchema = z.object({
title: z.string().min(1, "Title is required").max(255, "Title must be less than 255 characters"),
description: z.string().optional().default(""),
price: z.number().positive("Price must be positive"),
discountedPrice: z.number().positive("Discounted price must be positive"),
stock: z.number().nonnegative("Stock must be non-negative").optional().default(0),
sku: z.string().optional(),
categoryId: z.number().positive("Category ID must be positive"),
images: z
.array(
z.object({
url: z.string().url("Invalid image URL"),
type: z.enum(["THUMBNAIL", "PREVIEW"])})
)
.optional()});
export const updateProductSchema = z.object({
title: z.string().min(1).max(255).optional(),
description: z.string().optional(),
price: z.number().positive().optional(),
discountedPrice: z.number().positive().optional(),
stock: z.number().nonnegative().optional(),
sku: z.string().optional(),
categoryId: z.number().positive().optional()});
export type CreateProductInput = z.infer<typeof createProductSchema>;
export type UpdateProductInput = z.infer<typeof updateProductSchema>;
// ============================================================================
// CATEGORY SCHEMAS
// ============================================================================
export const createCategorySchema = z.object({
title: z.string().min(1, "Title is required").max(255, "Title must be less than 255 characters"),
slug: z.string().optional(),
imageUrl: z.string().url("Invalid image URL").optional(),
description: z.string().optional()});
export type CreateCategoryInput = z.infer<typeof createCategorySchema>;
// ============================================================================
// CART SCHEMAS
// ============================================================================
export const addToCartSchema = z.object({
productId: z.coerce.number().positive("Product ID must be positive"),
quantity: z.coerce.number().int().positive("Quantity must be at least 1")});
export const updateCartItemSchema = z.object({
quantity: z.coerce.number().int().positive("Quantity must be at least 1")});
export type AddToCartInput = z.infer<typeof addToCartSchema>;
export type UpdateCartItemInput = z.infer<typeof updateCartItemSchema>;
// ============================================================================
// WISHLIST SCHEMAS
// ============================================================================
export const addToWishlistSchema = z.object({
productId: z.coerce.number().positive("Product ID must be positive")});
export type AddToWishlistInput = z.infer<typeof addToWishlistSchema>;
// ============================================================================
// AUTH SCHEMAS
// ============================================================================
export const signupSchema = z.object({
email: z.string().email("Invalid email address"),
password: z.string().min(6, "Password must be at least 6 characters"),
name: z.string().min(1, "Name is required").optional(),
passwordConfirm: z.string()}).refine((data) => data.password === data.passwordConfirm, {
message: "Passwords do not match",
path: ["passwordConfirm"]});
export const signinSchema = z.object({
email: z.string().email("Invalid email address"),
password: z.string().min(1, "Password is required")});
export type SignupInput = z.infer<typeof signupSchema>;
export type SigninInput = z.infer<typeof signinSchema>;
// ============================================================================
// UTILITY FUNCTION
// ============================================================================
/**
* Safely parse and validate input data
* @param schema Zod schema to validate against
* @param data Data to validate
* @returns Validated data or null with error messages
*/
export function validateInput<T>(
schema: z.ZodSchema<T>,
data: unknown
): { success: boolean; data?: T; errors?: Record<string, string[]> } {
try {
const validatedData = schema.parse(data);
return { success: true, data: validatedData };
} catch (error) {
if (error instanceof z.ZodError) {
const errors: Record<string, string[]> = {};
error.issues.forEach((issue) => {
const path = issue.path.join(".");
if (!errors[path]) {
errors[path] = [];
}
errors[path].push(issue.message);
});
return { success: false, errors };
}
return { success: false, errors: { general: ["Validation failed"] } };
}
}
|