validateJsonSchema function

ValidationErrors validateJsonSchema(
  1. Object? object,
  2. Map<String, FieldSchema> schema
)

Validates a decoded JSON object against schema, returning a ValidationErrors collecting every problem (it never throws). Per field: a required field that is absent or null is missing; a present value of the wrong kind is type; a value outside an FieldSchema.allowed set is enum. A non-map object yields a single object-level type error.

Example:

validateJsonSchema(decoded, <String, FieldSchema>{
  'name': FieldSchema(JsonType.string),
  'age': FieldSchema(JsonType.integer, isRequired: false),
  'role': FieldSchema(JsonType.string, allowed: <Object?>['admin', 'user']),
});

Audited: 2026-06-12 11:26 EDT

Implementation

ValidationErrors validateJsonSchema(Object? object, Map<String, FieldSchema> schema) {
  final ValidationErrors errors = ValidationErrors();
  if (object is! Map) {
    errors.add(ValidationErrorUtils('expected object', code: 'type'));
    return errors;
  }
  for (final MapEntry<String, FieldSchema> entry in schema.entries) {
    final String key = entry.key;
    final FieldSchema field = entry.value;
    final Object? value = object[key];
    // Absent-or-null: only an error when the field is required.
    if (value == null) {
      if (field.isRequired) {
        errors.add(ValidationErrorUtils('missing required field', code: 'missing', path: key));
      }
      continue;
    }
    if (!_typeMatches(field.type, value)) {
      errors.add(ValidationErrorUtils('expected ${field.type.name}', code: 'type', path: key));
      continue;
    }
    final List<Object?>? allowed = field.allowed;
    if (allowed != null && !allowed.contains(value)) {
      errors.add(ValidationErrorUtils('value not in allowed set', code: 'enum', path: key));
    }
  }
  return errors;
}