class ConfigValidator {
constructor(schema) {
this.schema = schema;
}
validate(config) {
const errors = [];
this._validateObject(config, this.schema, '', errors);
return {
valid: errors.length === 0,
errors
};
}
_validateObject(obj, schema, path, errors) {
if (!schema.required) return;
for (const field of schema.required) {
const fieldPath = path ? `${path}.${field}` : field;
if (!(field in obj)) {
errors.push(`Missing required field: ${fieldPath}`);
}
}
for (const [key, value] of Object.entries(obj)) {
const fieldPath = path ? `${path}.${key}` : key;
const fieldSchema = schema.properties?.[key];
if (fieldSchema) {
this._validateValue(value, fieldSchema, fieldPath, errors);
}
}
}
_validateValue(value, schema, path, errors) {
if (schema.type === 'object' && schema.properties) {
this._validateObject(value, schema, path, errors);
} else if (schema.type === 'array' && schema.items) {
if (!Array.isArray(value)) {
errors.push(`${path}: expected array`);
} else {
value.forEach((item, i) => {
this._validateValue(item, schema.items, `${path}[${i}]`, errors);
});
}
} else if (schema.type && typeof value !== schema.type) {
errors.push(`${path}: expected ${schema.type}, got ${typeof value}`);
}
}
}
module.exports = ConfigValidator;