UNPKG

web-crawling-utils

Version:
141 lines (126 loc) 6.32 kB
import { Schema } from "./validationSchema"; /** * Validates data against a defined schema, checking for required fields, data types, * and additional constraints (e.g., min/max values, pattern matching). * * @function validate * @param {Schema} schema - A validation schema specifying rules for each field, * including type, required status, minimum/maximum constraints, and pattern matching. * @param {any} data - The input data to be validated against the schema. * @returns {string[]} - An array of validation error messages. If validation passes, * the array will be empty. * * @description This function iterates through each key in the provided schema to validate * the corresponding field in the data. It performs the following checks: * - **Required Fields**: Ensures required fields are present. * - **Type Validation**: Validates the type (e.g., string, number, boolean, array, object, date). * - **String Constraints**: Checks min/max length and pattern matching for strings. * - **Number Constraints**: Enforces min/max values for numbers. * - **Array Validation**: Validates arrays of strings or numbers. * - **Object Validation**: Supports nested object validation through recursive calls. * - **Enum Validation**: Confirms values match one of a specified list. * * @example * const schema = { * name: { type: "string", required: true, minLength: 3 }, * age: { type: "number", min: 18, max: 99 }, * preferences: { type: "array:string" }, * }; * * const data = { name: "Alice", age: 25, preferences: ["reading", "swimming"] }; * const errors = validate(schema, data); * * @remarks * This function provides a centralized validation approach to enforce data integrity and * prevent invalid inputs from entering the application, supporting a uniform data format. * If validation fails, it returns an array of descriptive error messages, highlighting the * fields that do not meet the specified criteria. */ export function validate(schema: Schema, data: any): string[] { try { let errors: string[] = []; for (const key in schema) { const rules = schema[key]; const value = data[key]; // Check if the field is required and missing if (rules.required && (value === undefined || value === null)) { errors.push(`${key} is required.`); continue; } // Skip further checks if the value is not required and is not present if (value === undefined || value === null) { continue; } // Check the type of the value if (rules.type) { switch (rules.type) { case "string": if (typeof value !== "string") { errors.push(`${key} must be a string.`); } if (rules.minLength && value.length < rules.minLength) { errors.push(`${key} must be at least ${rules.minLength} characters long.`); } if (rules.maxLength && value.length > rules.maxLength) { errors.push(`${key} must be no more than ${rules.maxLength} characters long.`); } if (rules.pattern && !rules.pattern.test(value)) { errors.push(`${key} must match the pattern ${rules.pattern}.`); } break; case "number": if (typeof value !== "number") { errors.push(`${key} must be a number.`); } if (rules.min && value < rules.min) { errors.push(`${key} must be at least ${rules.min}.`); } if (rules.max && value > rules.max) { errors.push(`${key} must be no more than ${rules.max}.`); } break; case "boolean": if (typeof value !== "boolean") { errors.push(`${key} must be a boolean.`); } break; case "array:string": if (!Array.isArray(value) || !value.every(item => typeof item === "string")) { errors.push(`${key} must be an array of strings.`); } break; case "array:number": if (!Array.isArray(value) || !value.every(item => typeof item === "number")) { errors.push(`${key} must be an array of numbers.`); } break; case "object": if (typeof value !== "object" || Array.isArray(value)) { errors.push(`${key} must be an object.`); } else if (rules.properties) { // Recursively validate nested object const nestedErrors = validate(rules.properties, value); errors.push(...nestedErrors.map(err => `${key}.${err}`)); } break; case "date": if (isNaN(Date.parse(value))) { errors.push(`${key} must be a valid date.`); } break; case "enum": if (rules.enum && !rules.enum.includes(value)) { errors.push(`${key} must be one of [${rules.enum.join(", ")}].`); } break; default: errors.push(`${key} has an unknown type: ${rules.type}.`); } } } return errors; } catch (error) { console.log(error); throw error; } }