/**
* Validates JSON payloads for development use with synchronous execution.
*
* @param {object} schema - The JSON schema to validate against.
* @param {object} data - The JSON data to validate.
* @returns {object} - An object containing validation results. {valid: boolean, errors: array}
*/
function validateJson(schema, data) {
const errors = [];
if (typeof schema !== 'object' || schema === null) {
return { valid: false, errors: [{ message: 'Schema must be an object.' }] };
}
if (typeof data !== 'object' || data === null) {
return { valid: false, errors: [{ message: 'Data must be an object.' }] };
}
function validateProperty(propertyName, schemaProperty, dataValue) {
if (schemaProperty.required && !dataValue.hasOwnProperty(propertyName)) {
errors.push({ message: `Missing required property: ${propertyName}` });
return;
}
if (schemaProperty.type) {
switch (schemaProperty.type) {
case 'string':
if (typeof dataValue !== 'string') {
errors.push({ message: `Property ${propertyName} must be a string.` });
}
break;
case 'number':
if (typeof dataValue !== 'number' || isNaN(dataValue)) {
errors.push({ message: `Property ${propertyName} must be a number.` });
}
break;
case 'boolean':
if (typeof dataValue !== 'boolean') {
errors.push({ message: `Property ${propertyName} must be a boolean.` });
}
break;
case 'array':
if (!Array.isArray(dataValue)) {
errors.push({ message: `Property ${propertyName} must be an array.` });
}
break;
case 'object':
if (typeof dataValue !== 'object' || dataValue === null) {
errors.push({ message: `Property ${propertyName} must be an object.` });
}
break;
default:
console.warn(`Unknown type: ${schemaProperty.type} for property ${propertyName}`);
}
}
if (schemaProperty.enum && !schemaProperty.enum.includes(dataValue)) {
errors.push({ message: `Property ${propertyName} must be one of: ${schemaProperty.enum.join(', ')}` });
}
if (schemaProperty.minLength && String(dataValue).length < schemaProperty.minLength) {
errors.push({ message: `Property ${propertyName} must be at least ${schemaProperty.minLength} characters long.` });
}
if (schemaProperty.maxLength && String(dataValue).length > schemaProperty.maxLength) {
errors.push({ message: `Property ${propertyName} must be at most ${schemaProperty.maxLength} characters long.` });
}
if (schemaProperty.pattern && !new RegExp(schemaProperty.pattern).test(String(dataValue))) {
errors.push({ message: `Property ${propertyName} must match pattern: ${schemaProperty.pattern}` });
}
if (schemaProperty.properties) {
if (typeof schemaProperty.properties !== 'object' || schemaProperty.properties === null) {
errors.push({message: `Properties must be an object`});
return;
}
for (const propName in schemaProperty.properties) {
if (schemaProperty.properties.hasOwnProperty(propName)) {
validateProperty(propName, schemaProperty.properties[propName], dataValue);
}
}
}
}
for (const key in schema) {
if (schema.hasOwnProperty(key)) {
const schemaProperty = schema[key];
if (typeof schemaProperty === 'object' && schemaProperty !== null) {
if (Array.isArray(schemaProperty)) {
for(const item of schemaProperty){
if(typeof item === 'object' && item !== null){
validateProperty(key, item, data[key]);
} else {
errors.push({message: `Invalid item in array at key ${key}` });
}
}
} else {
validateProperty(key, schemaProperty, data[key]);
}
}
Add your comment