martinms

Untitled

Oct 5th, 2025
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.42 KB | None | 0 0
  1. /**
  2.  * Validation Utility
  3.  *
  4.  * This utility provides a centralized way to handle Zod validation
  5.  * with consistent error responses. It returns validated data on success
  6.  * or a standardized 422 error response on validation failure.
  7.  *
  8.  * @author Sahabat Ibu Hamil Team
  9.  * @version 1.0.0
  10.  */
  11.  
  12. import { z } from 'zod';
  13. import type { Response } from 'express';
  14.  
  15. /**
  16.  * Validation result type for successful validation
  17.  */
  18. export interface ValidationSuccess<T> {
  19.   success: true;
  20.   data: T;
  21. }
  22.  
  23. /**
  24.  * Validation result type for failed validation
  25.  */
  26. export interface ValidationError<TDetails = unknown> {
  27.   success: false;
  28.   error: {
  29.     message: string;
  30.     details: TDetails;
  31.   };
  32. }
  33.  
  34. /**
  35.  * Union type for validation results
  36.  */
  37. export type ValidationResult<T> = ValidationSuccess<T> | ValidationError;
  38.  
  39. /**
  40.  * Formats Zod validation errors to a cleaner structure
  41.  * Converts from { field: { _errors: [...] } } to { field: [...] }
  42.  *
  43.  * @param zodError - The Zod error object
  44.  * @returns Formatted error object with field names as keys and error arrays as values
  45.  */
  46. function formatValidationErrors(zodError: z.ZodError): Record<string, string[]> {
  47.   const formatted: Record<string, string[]> = {};
  48.  
  49.   zodError.issues.forEach((issue) => {
  50.     const field = issue.path.join('.');
  51.     if (!formatted[field]) {
  52.       formatted[field] = [];
  53.     }
  54.     formatted[field].push(issue.message);
  55.   });
  56.  
  57.   return formatted;
  58. }
  59.  
  60. /**
  61.  * Validates request data using a Zod schema and returns the result
  62.  *
  63.  * @param schema - The Zod schema to validate against
  64.  * @param data - The data to validate
  65.  * @returns ValidationResult containing either success with data or error details
  66.  */
  67. export function validateData<T>(
  68.   schema: z.ZodSchema<T>,
  69.   data: unknown
  70. ): ValidationResult<T> {
  71.   const result = schema.safeParse(data);
  72.  
  73.   if (result.success) {
  74.     return {
  75.       success: true,
  76.       data: result.data
  77.     };
  78.   }
  79.  
  80.   return {
  81.     success: false,
  82.     error: {
  83.       message: 'Validasi gagal',
  84.       details: formatValidationErrors(result.error)
  85.     }
  86.   };
  87. }
  88.  
  89. /**
  90.  * Validates request data and automatically sends 422 response on validation failure
  91.  * Returns the validated data if successful, or null if validation failed (response already sent)
  92.  *
  93.  * @param schema - The Zod schema to validate against
  94.  * @param data - The data to validate
  95.  * @param res - Express response object
  96.  * @returns Validated data on success, null on failure (response already sent)
  97.  */
  98. export function validateAndRespond<T>(
  99.   schema: z.ZodSchema<T>,
  100.   data: unknown,
  101.   res: Response
  102. ): T | null {
  103.   const validationResult = validateData(schema, data);
  104.  
  105.   if (validationResult.success) {
  106.     return validationResult.data;
  107.   }
  108.  
  109.   // Send 422 Unprocessable Entity response
  110.   res.status(422).json({
  111.     success: false,
  112.     message: validationResult.error.message,
  113.     errors: validationResult.error.details
  114.   });
  115.  
  116.   return null;
  117. }
  118.  
  119. /**
  120.  * Async version of validateAndRespond for use with async/await
  121.  *
  122.  * @param schema - The Zod schema to validate against
  123.  * @param data - The data to validate
  124.  * @param res - Express response object
  125.  * @returns Promise that resolves to validated data on success, null on failure
  126.  */
  127. export async function validateAndRespondAsync<T>(
  128.   schema: z.ZodSchema<T>,
  129.   data: unknown,
  130.   res: Response
  131. ): Promise<T | null> {
  132.   return validateAndRespond(schema, data, res);
  133. }
Advertisement
Add Comment
Please, Sign In to add comment