global
def build_array_items_schema(array, record: nil, path: nil, context: nil)
def build_array_items_schema(array, record: nil, path: nil, context: nil) return {} if array.empty? return build_property(array.first, record: record, path: path, context: context) if array.size == 1 return build_property(array.first, record: record, path: path, context: context) unless array.all? { |item| item.is_a?(Hash) } all_schemas = array.map { |item| build_property(item, record: record, path: path, context: context) } merged_schema = all_schemas.first.dup merged_schema[:properties] = {} all_keys = all_schemas.flat_map { |s| s[:properties]&.keys || [] }.uniq all_keys.each do |key| all_property_schemas = all_schemas.map { |s| s[:properties]&.[](key) } nullable_only_schemas = all_property_schemas.select { |p| p && p.keys == [:nullable] } property_variations = all_property_schemas.select { |p| p && p.keys != [:nullable] } has_nullable = all_property_schemas.any?(&:nil?) || nullable_only_schemas.any? next if property_variations.empty? && !has_nullable if property_variations.empty? && has_nullable merged_schema[:properties][key] = { nullable: true } elsif property_variations.size == 1 merged_schema[:properties][key] = property_variations.first.dup else unique_types = property_variations.map { |p| p[:type] }.compact.uniq if unique_types.size > 1 unique_props = property_variations.map { |p| p.reject { |k, _| k == :nullable } }.uniq merged_schema[:properties][key] = { oneOf: unique_props } else case unique_types.first when 'array' merged_schema[:properties][key] = { type: 'array' } items_variations = property_variations.map { |p| p[:items] }.compact merged_schema[:properties][key][:items] = build_merged_schema_from_variations(items_variations) when 'object' merged_schema[:properties][key] = build_merged_schema_from_variations(property_variations) else merged_schema[:properties][key] = property_variations.first.dup end end end merged_schema[:properties][key][:nullable] = true if has_nullable && merged_schema[:properties][key].is_a?(Hash) end all_required_sets = all_schemas.map { |s| s[:required] || [] } merged_schema[:required] = all_required_sets.reduce(:&) || [] merged_schema end