schemable/lib/schemable/response_schema_generator.rb
2023-11-17 17:15:23 +03:00

89 lines
2.5 KiB
Ruby

module Schemable
class ResponseSchemaGenerator
attr_reader :model_definition, :model, :schema_modifier, :configuration
def initialize(model_definition)
@model_definition = model_definition
@model = model_definition.model
@schema_modifier = SchemaModifier.new
@configuration = Schemable.configuration
end
def generate(expand: false, relationships_to_exclude_from_expansion: [], collection: false)
data = {
type: :object,
properties: {
type: { type: :string, default: @model_definition.model_name },
id: { type: :string },
attributes: AttributeSchemaGenerator.new(@model_definition).generate
}.merge(
if @model_definition.relationships.blank? || @model_definition.relationships == { belongs_to: {}, has_many: {} }
{}
else
{ relationships: RelationshipSchemaGenerator.new(@model_definition).generate(expand:, relationships_to_exclude_from_expansion:) }
end
)
}
schema = collection ? { data: { type: :array, items: data } } : { data: }
if expand
included_schema = IncludedSchemaGenerator.new(@model_definition).generate(expand:, relationships_to_exclude_from_expansion:)
@schema_modifier.add_properties(schema, included_schema, '.')
end
@schema_modifier.add_properties(schema, { meta: }, '.') if collection
@schema_modifier.add_properties(schema, { jsonapi: }, '.')
{ type: :object, properties: schema }.compact_blank
end
def meta
return @configuration.custom_meta_response_schema if @configuration.custom_meta_response_schema.present?
if @configuration.pagination_enabled
{
type: :object,
properties: {
page: {
type: :object,
properties: {
totalPages: {
type: :integer,
default: 1
},
count: {
type: :integer,
default: 1
},
rowsPerPage: {
type: :integer,
default: 1
},
currentPage: {
type: :integer,
default: 1
}
}
}
}
}
else
{}
end
end
def jsonapi
{
type: :object,
properties: {
version: {
type: :string,
default: '1.0'
}
}
}
end
end
end