|
| 1 | +class OpenAPIParser::Schema31Validator |
| 2 | + class ObjectValidator < Base |
| 3 | + # @param [Hash] value |
| 4 | + # @param [OpenAPIParser::Schemas31Schema] schema |
| 5 | + # @param [Boolean] parent_all_of true if component is nested under allOf |
| 6 | + # @param [String, nil] discriminator_property_name discriminator.property_name to ignore checking additional_properties |
| 7 | + def coerce_and_validate(value, schema, parent_all_of: false, parent_discriminator_schemas: [], discriminator_property_name: nil) |
| 8 | + return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(Hash) |
| 9 | + |
| 10 | + properties = schema.properties || {} |
| 11 | + |
| 12 | + required_set = schema.required ? schema.required.to_set : Set.new |
| 13 | + remaining_keys = value.keys |
| 14 | + |
| 15 | + if schema.discriminator && !parent_discriminator_schemas.include?(schema) |
| 16 | + return validate_discriminator_schema( |
| 17 | + schema.discriminator, |
| 18 | + value, |
| 19 | + parent_discriminator_schemas: parent_discriminator_schemas + [schema] |
| 20 | + ) |
| 21 | + else |
| 22 | + remaining_keys.delete('discriminator') |
| 23 | + end |
| 24 | + |
| 25 | + coerced_values = value.map do |name, v| |
| 26 | + s = properties[name] |
| 27 | + coerced, err = if s |
| 28 | + remaining_keys.delete(name) |
| 29 | + validatable.validate_schema(v, s) |
| 30 | + else |
| 31 | + # TODO: we need to perform a validation based on schema.additional_properties here, if |
| 32 | + # additionalProperties are defined |
| 33 | + [v, nil] |
| 34 | + end |
| 35 | + |
| 36 | + return [nil, err] if err |
| 37 | + |
| 38 | + required_set.delete(name) |
| 39 | + [name, coerced] |
| 40 | + end |
| 41 | + |
| 42 | + remaining_keys.delete(discriminator_property_name) if discriminator_property_name |
| 43 | + |
| 44 | + if !remaining_keys.empty? && !parent_all_of && !schema.additional_properties |
| 45 | + # If object is nested in all of, the validation is already done in allOf validator. Or if |
| 46 | + # additionalProperties are defined, we will validate using that |
| 47 | + return [nil, OpenAPIParser::NotExistPropertyDefinition.new(remaining_keys, schema.object_reference)] |
| 48 | + end |
| 49 | + return [nil, OpenAPIParser::NotExistRequiredKey.new(required_set.to_a, schema.object_reference)] unless required_set.empty? |
| 50 | + |
| 51 | + value.merge!(coerced_values.to_h) if @coerce_value |
| 52 | + |
| 53 | + [value, nil] |
| 54 | + end |
| 55 | + end |
| 56 | +end |
0 commit comments