UNPKG

api-req-validator

Version:
112 lines (111 loc) 4.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateSchema = void 0; class ApiSchemaValidator { constructor() { this.errors = []; } validateValidationRule(rule, path) { // Check if the rule is an object if (typeof rule !== 'object' || rule === null) { this.errors.push(`${path}: Must be an object`); return; } // Check for unknown properties Object.keys(rule).forEach(key => { if (!ApiSchemaValidator.validProperties.includes(key)) { this.errors.push(`${path}: Unknown property '${key}'`); } }); // Validate required property if ('required' in rule && typeof rule.required !== 'boolean') { this.errors.push(`${path}: 'required' must be a boolean`); } // Validate dataType if ('dataType' in rule && typeof rule.dataType === 'string' && !ApiSchemaValidator.validDataTypes.includes(rule.dataType)) { this.errors.push(`${path}: Invalid dataType '${rule.dataType}'`); } // Validate regex if ('regex' in rule && typeof rule.regex !== 'string') { this.errors.push(`${path}: 'regex' must be a string`); } // Validate min/max/length if ('min' in rule && typeof rule.min !== 'number') { this.errors.push(`${path}: 'min' must be a number`); } if ('max' in rule && typeof rule.max !== 'number') { this.errors.push(`${path}: 'max' must be a number`); } if ('length' in rule && typeof rule.length !== 'number') { this.errors.push(`${path}: 'length' must be a number`); } // Validate allowedValues if ('allowedValues' in rule) { if (!Array.isArray(rule.allowedValues)) { this.errors.push(`${path}: 'allowedValues' must be an array`); } } } isValidationRule(obj) { return obj && typeof obj === 'object' && ('dataType' in obj || 'required' in obj || 'regex' in obj || 'min' in obj || 'max' in obj || 'length' in obj || 'allowedValues' in obj); } validateNestedStructure(obj, path) { if (typeof obj !== 'object' || obj === null) { this.errors.push(`${path}: Must be an object`); return; } Object.entries(obj).forEach(([key, value]) => { const newPath = path ? `${path}.${key}` : key; if (this.isValidationRule(value)) { this.validateValidationRule(value, newPath); } else if (typeof value === 'object' && value !== null) { this.validateNestedStructure(value, newPath); } else { this.errors.push(`${newPath}: Invalid schema structure`); } }); } schemaValidator(schema) { if (typeof schema !== 'object' || schema === null) { this.errors.push('Schema must be an object'); return { isValid: false, error: this.errors }; } // Validate each route Object.entries(schema).forEach(([route, routeSchema]) => { if (typeof route !== 'string') { this.errors.push('Route must be a string'); return { isValid: false, error: this.errors }; } if (typeof routeSchema !== 'object' || routeSchema === null) { this.errors.push(`Route '${route}': Must contain an object of validation rules`); return { isValid: false, error: this.errors }; } this.validateNestedStructure(routeSchema, route); }); return { isValid: this.errors.length === 0, error: this.errors }; } } ApiSchemaValidator.validDataTypes = [ "int", "string", "array+number", "array+string", "array+mobile", "array+bool", "array+float", "date", "mobile", "bool", "alpha", "alphanumeric", "float", "email" ]; ApiSchemaValidator.validProperties = ['required', 'dataType', 'regex', 'min', 'max', 'length', 'allowedValues']; const validateSchema = (apiSchema) => { const validator = new ApiSchemaValidator(); const result = validator.schemaValidator(apiSchema); if (result.isValid) return true; else return false; }; exports.validateSchema = validateSchema;