Skip to content

Instantly share code, notes, and snippets.

@MrTin
Created January 9, 2025 08:01
Show Gist options
  • Save MrTin/cac715e5b7c2dbf7379effa61cb27cab to your computer and use it in GitHub Desktop.
Save MrTin/cac715e5b7c2dbf7379effa61cb27cab to your computer and use it in GitHub Desktop.
JSON Schema Validation with support for conditionals
export const jsonSchemaToValidation = (schema, watchedValues = {}) => {
const rules = {};
// Process conditional requirements from allOf
const getConditionalRequiredFields = () => {
const conditionalRequired = new Set(schema.required || []);
if (schema.allOf) {
schema.allOf.forEach(condition => {
if (condition.if && condition.then) {
const ifProps = condition.if.properties;
const matches = Object.entries(ifProps).every(
([field, value]) => watchedValues[field] === value.const
);
if (matches && condition.then.required) {
condition.then.required.forEach(field => conditionalRequired.add(field));
}
}
});
}
return conditionalRequired;
};
const requiredFields = getConditionalRequiredFields();
Object.entries(schema.properties).forEach(([field, definition]) => {
rules[field] = {
required: requiredFields.has(field) && 'This field is required',
};
if (definition.type === 'string') {
if (definition.minLength) {
rules[field].minLength = {
value: definition.minLength,
message: `Minimum length is ${definition.minLength} characters`,
};
}
if (definition.maxLength) {
rules[field].maxLength = {
value: definition.maxLength,
message: `Maximum length is ${definition.maxLength} characters`,
};
}
if (definition.pattern) {
rules[field].pattern = {
value: new RegExp(definition.pattern),
message: definition.description || 'Invalid format',
};
}
if (definition.format === 'email') {
rules[field].pattern = {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: 'Invalid email address',
};
}
}
if (definition.type === 'integer' || definition.type === 'number') {
rules[field].valueAsNumber = true;
if (definition.minimum !== undefined) {
rules[field].min = {
value: definition.minimum,
message: `Minimum value is ${definition.minimum}`,
};
}
if (definition.maximum !== undefined) {
rules[field].max = {
value: definition.maximum,
message: `Maximum value is ${definition.maximum}`,
};
}
}
});
return rules;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment