UNPKG

@syntropysoft/praetorian

Version:

Praetorian CLI – A universal multi-environment configuration validator for DevSecOps teams. Validate, compare, and secure YAML/ENV files with ease.

209 lines 7.07 kB
"use strict"; /** * Structure Validator - Functional Programming * * Single Responsibility: Validate object and array structures only * Pure functions, no state, no side effects */ Object.defineProperty(exports, "__esModule", { value: true }); exports.validateRequiredProperties = exports.validateValue = exports.validateArray = exports.validateObject = void 0; const TypeValidator_1 = require("./TypeValidator"); const FormatValidator_1 = require("./FormatValidator"); const RangeValidator_1 = require("./RangeValidator"); /** * Pure function to validate object structure */ const validateObject = (value, schema, path, errors, warnings, context) => { // Guard clause: not an object if (!isObject(value)) { return; } // Guard clause: no properties defined if (!schema.properties) { return; } // Validate required properties first const requiredErrors = (0, exports.validateRequiredProperties)(value, schema, path); errors.push(...requiredErrors); // Validate known properties Object.entries(schema.properties).forEach(([key, propSchema]) => { const propPath = buildPath(path, key); const propErrors = (0, exports.validateValue)(value[key], propSchema, propPath, context); errors.push(...propErrors); }); // Check for additional properties const additionalErrors = validateAdditionalProperties(value, schema, path); errors.push(...additionalErrors); }; exports.validateObject = validateObject; /** * Pure function to validate array structure */ const validateArray = (value, schema, path, errors, warnings, context) => { // Guard clause: not an array if (!Array.isArray(value)) { return; } // Guard clause: no items schema if (!schema.items) { return; } const arrayErrors = Array.isArray(schema.items) ? validateTuple(value, schema.items, path, context) : validateArrayItems(value, schema.items, path, context); errors.push(...arrayErrors); }; exports.validateArray = validateArray; /** * Pure function to validate tuple array */ const validateTuple = (value, itemSchemas, path, context) => { return value.flatMap((item, i) => { const itemSchema = itemSchemas[i] || itemSchemas[itemSchemas.length - 1]; const itemPath = buildArrayPath(path, i); return (0, exports.validateValue)(item, itemSchema, itemPath, context); }); }; /** * Pure function to validate array items */ const validateArrayItems = (value, itemSchema, path, context) => { return value.flatMap((item, i) => { const itemPath = buildArrayPath(path, i); return (0, exports.validateValue)(item, itemSchema, itemPath, context); }); }; /** * Pure function to validate additional properties */ const validateAdditionalProperties = (value, schema, path) => { // Guard clause: additional properties allowed if (schema.additionalProperties !== false) { return []; } const knownProps = new Set(Object.keys(schema.properties || {})); return Object.keys(value) .filter(key => !knownProps.has(key)) .map(key => createAdditionalPropertyError(buildPath(path, key), key)); }; /** * Pure function to validate a value against schema (delegates to specialized validators) */ const validateValue = (value, schema, path, context) => { return [ // Type validation ...(0, TypeValidator_1.validateType)(value, schema, path), // Format validation ...(0, FormatValidator_1.validateFormat)(value, schema, path), ...(0, FormatValidator_1.validatePattern)(value, schema, path), // Range validation ...(0, RangeValidator_1.validateStringLength)(value, schema, path), ...(0, RangeValidator_1.validateNumberRange)(value, schema, path), // Enum validation ...validateEnum(value, schema, path), // Structure validation ...validateObjectStructure(value, schema, path, context), ...validateArrayStructure(value, schema, path, context) ]; }; exports.validateValue = validateValue; /** * Pure function to validate object structure */ const validateObjectStructure = (value, schema, path, context) => { if (schema.type === 'object' && isObject(value)) { const errors = []; const warnings = []; (0, exports.validateObject)(value, schema, path, errors, warnings, context); return errors; } return []; }; /** * Pure function to validate array structure */ const validateArrayStructure = (value, schema, path, context) => { if (schema.type === 'array' && Array.isArray(value)) { const errors = []; const warnings = []; (0, exports.validateArray)(value, schema, path, errors, warnings, context); return errors; } return []; }; /** * Pure function to validate enum values */ const validateEnum = (value, schema, path) => { // Guard clause: no enum defined if (!schema.enum) { return []; } return !schema.enum.includes(value) ? [createEnumError(path, value, schema.enum)] : []; }; /** * Pure function to check if value is object */ const isObject = (value) => typeof value === 'object' && !Array.isArray(value) && value !== null; /** * Pure function to build property path */ const buildPath = (basePath, key) => basePath ? `${basePath}.${key}` : key; /** * Pure function to build array path */ const buildArrayPath = (basePath, index) => `${basePath}[${index}]`; /** * Pure function to create additional property error */ const createAdditionalPropertyError = (path, key) => ({ path, message: `Additional property '${key}' is not allowed`, code: 'ADDITIONAL_PROPERTY_NOT_ALLOWED', actual: key }); /** * Pure function to create enum error */ const createEnumError = (path, value, enumValues) => ({ path, message: `Value must be one of: ${enumValues.join(', ')}`, code: 'INVALID_ENUM', actual: value, expected: enumValues }); /** * Pure function to validate required properties */ const validateRequiredProperties = (value, schema, path) => { // Guard clause: no required properties if (!schema.required || !Array.isArray(schema.required)) { return []; } // Guard clause: not an object if (!isObject(value)) { return []; } const errors = []; // Check each required property schema.required.forEach(propName => { if (!(propName in value) || value[propName] === undefined || value[propName] === null) { errors.push(createRequiredPropertyError(buildPath(path, propName), propName)); } }); return errors; }; exports.validateRequiredProperties = validateRequiredProperties; /** * Pure function to create required property error */ const createRequiredPropertyError = (path, propName) => ({ path, message: `Required property '${propName}' is missing`, code: 'REQUIRED_PROPERTY_MISSING', actual: undefined, expected: propName }); //# sourceMappingURL=StructureValidator.js.map