import { Request, Response, NextFunction } from 'express'; import { z } from 'zod'; import type { ApiResponse, GetInfoRequest } from '../types/index.js'; import { isSupportedContentUrl } from '../utils/contentUrl.js'; /** * Validation schema for /api/getinfo endpoint */ const getInfoSchema = z.object({ url: z .string() .url('Invalid URL format') .refine( (url) => isSupportedContentUrl(url), 'URL must be Netflix /title/... or PrimeVideo /detail/...' ), }); /** * Validate request body for /api/getinfo */ export function validateGetInfo( req: Request, res: Response, next: NextFunction ): void { const result = getInfoSchema.safeParse(req.body); if (!result.success) { const errors = result.error.issues.map((issue) => ({ field: issue.path.join('.'), message: issue.message, })); const response: ApiResponse = { success: false, error: { code: 'VALIDATION_ERROR', message: 'Invalid request parameters', details: { errors }, }, }; res.status(400).json(response); return; } // Attach validated data to request (req as Request & { validated: GetInfoRequest }).validated = result.data; next(); } /** * Generic validation middleware factory */ export function validateBody( schema: T ): (req: Request, res: Response, next: NextFunction) => void { return (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) { const errors = result.error.issues.map((issue) => ({ field: issue.path.join('.'), message: issue.message, })); const response: ApiResponse = { success: false, error: { code: 'VALIDATION_ERROR', message: 'Invalid request parameters', details: { errors }, }, }; res.status(400).json(response); return; } next(); }; } export default validateGetInfo;