From 2d7dd77f6e0cdb7ec18a6dc4a3c9a6f7ccda89c6 Mon Sep 17 00:00:00 2001 From: Muhammad Nawzad Date: Sun, 12 Nov 2023 11:01:51 +0300 Subject: [PATCH] Adds ResponseSchemaGenerator Class --- lib/schemable/response_schema_generator.rb | 81 +++++++++++++++++++++ sig/schemable/response_schema_generator.rbs | 12 +++ 2 files changed, 93 insertions(+) create mode 100644 lib/schemable/response_schema_generator.rb create mode 100644 sig/schemable/response_schema_generator.rbs diff --git a/lib/schemable/response_schema_generator.rb b/lib/schemable/response_schema_generator.rb new file mode 100644 index 0000000..312206f --- /dev/null +++ b/lib/schemable/response_schema_generator.rb @@ -0,0 +1,81 @@ +module Schemable + class ResponseSchemaGenerator + attr_accessor :model_definition, :model + + def initialize(model_definition) + @model_definition = model_definition + @model = model_definition.model + @schema_modifier = SchemaModifier.new + 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 } + end + + def meta + { + 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 + } + } + } + } + } + end + + def jsonapi + { + type: :object, + properties: { + version: { + type: :string, + default: '1.0' + } + } + } + end + end +end diff --git a/sig/schemable/response_schema_generator.rbs b/sig/schemable/response_schema_generator.rbs new file mode 100644 index 0000000..f09bee5 --- /dev/null +++ b/sig/schemable/response_schema_generator.rbs @@ -0,0 +1,12 @@ +module Schemable + class ResponseSchemaGenerator + attr_accessor model: Class + attr_accessor model_definition: Definition + attr_accessor schema_modifier: SchemaModifier + + def initialize: (Definition) -> void + def meta: -> Hash[Symbol, any] + def jsonapi: -> Hash[Symbol, any] + def generate: (expand: bool, relationships_to_exclude_from_expansion: Array[Symbol], collection: bool) -> Hash[Symbol, any] + end +end