class WCC::Contentful::Graphql::Builder
Attributes
root_types[R]
schema_types[R]
Public Class Methods
new(types, store)
click to toggle source
# File lib/wcc/contentful/graphql/builder.rb, line 15 def initialize(types, store) @types = types if types.is_a? WCC::Contentful::IndexedRepresentation @types ||= if types.is_a?(String) && File.exist?(types) WCC::Contentful::ContentTypeIndexer.load(types).types end unless @types raise ArgumentError, 'Cannot parse types - not an IndexedRepresentation ' \ "nor a schema file on disk: #{types}" end @store = store @schema_types = build_schema_types @root_types = @schema_types.dup end
Public Instance Methods
build_schema()
click to toggle source
# File lib/wcc/contentful/graphql/builder.rb, line 38 def build_schema root_query_type = build_root_query(root_types) builder = self GraphQL::Schema.define do query root_query_type resolve_type ->(_type, obj, _ctx) { content_type = WCC::Contentful::Helpers.content_type_from_raw(obj) builder.schema_types[content_type] } end end
configure(&block)
click to toggle source
# File lib/wcc/contentful/graphql/builder.rb, line 33 def configure(&block) instance_exec(&block) self end
Private Instance Methods
build_root_query(schema_types)
click to toggle source
# File lib/wcc/contentful/graphql/builder.rb, line 54 def build_root_query(schema_types) store = @store GraphQL::ObjectType.define do name 'Query' description 'The query root of this schema' schema_types.each do |content_type, schema_type| field schema_type.name.to_sym do type schema_type argument :id, types.ID description "Find a #{schema_type.name}" schema_type.fields.each do |(name, field)| next unless input_type = Types::QueryOperatorInput.call(field.type) argument name, input_type end resolve ->(_obj, args, _ctx) { if args['id'].nil? store.find_by(content_type: content_type, filter: args.to_h) else store.find(args['id']) end } end field "all#{schema_type.name}".to_sym do type schema_type.to_list_type argument :filter, Types::FilterInputType.call(schema_type) resolve ->(_obj, args, ctx) { relation = store.find_all(content_type: content_type) relation = relation.apply(args[:filter].to_h, ctx) if args[:filter] relation.to_enum } end end end end
build_schema_type(typedef)
click to toggle source
# File lib/wcc/contentful/graphql/builder.rb, line 102 def build_schema_type(typedef) store = @store builder = self content_type = typedef.content_type GraphQL::ObjectType.define do name(typedef.name) description("Generated from content type #{content_type}") field :id, !types.ID do resolve ->(obj, _args, _ctx) { obj.dig('sys', 'id') } end field :_content_type, !types.String do resolve ->(_, _, _) { content_type } end # Make a field for each column: typedef.fields.each_value do |f| case f.type when :Asset field(f.name.to_sym, -> { type = builder.schema_types['Asset'] type = type.to_list_type if f.array type }) do resolve contentful_link_resolver(f.name, store: store) end when :Link field(f.name.to_sym, -> { type = if f.link_types.nil? || f.link_types.empty? builder.schema_types['AnyContentful'] ||= Types::BuildUnionType.call(builder.schema_types, 'AnyContentful') elsif f.link_types.length == 1 builder.schema_types[f.link_types.first] else from_types = builder.schema_types.select { |key| f.link_types.include?(key) } name = "#{typedef.name}_#{f.name}" builder.schema_types[name] ||= Types::BuildUnionType.call(from_types, name) end type = type.to_list_type if f.array type }) do resolve contentful_link_resolver(f.name, store: store) end else contentful_field(f.name, f.type, array: f.array) end end end end
build_schema_types()
click to toggle source
# File lib/wcc/contentful/graphql/builder.rb, line 96 def build_schema_types @types.each_with_object({}) do |(k, v), h| h[k] = build_schema_type(v) end end