module Ecoportal module API class GraphQL module Base class Query class GenericItem def initialize(*args, **kargs) raise "Missuse error. You should define a item_class for a class that inherits from Query class." end end include Ecoportal::API::Common::GraphQL::ClassHelpers inheritable_attrs :accepted_params class << self def accepted_params(*keys) @accepted_params ||= [] return @accepted_params if keys.empty? @accepted_params.push(*keys).tap {|ks| ks.uniq!} end def clear_accepted_params @accepted_params = [] end def slice_params(kargs) kargs.slice(*accepted_params) end # Used to obtain the full `path` in the GraphQL query by using `base_path` # @note it is meant for reusability of queries from different end-points def field_name(str = nil) return @field_name unless str @field_name = nil @field_name = str.to_s if str end end class_resolver :item_class, GenericItem attr_reader :client attr_reader :base_path def initialize(client, path: nil, base_path: nil) @path = path @base_path = base_path @client = client end # Resolves the `path` by using `path` or `base_path` + `class.field_name`. def path(field_name = self.class.field_name) result = @path result ||= default_path if self.respond_to?(:default_path, true) result ||= (base_path + [field_name]) if base_path && field_name result end # Query rely that manages the different blocks. # @return [Class] an object of `response_class` with the results hanging from `path`. def query(path: self.path, **kargs, &block) graphql_query(path: path, **kargs, &basic_block(&block)) end def response_class item_class end def access_point(path = []) path.last end private def basic_block raise "This method should be implemented in the child class #{self.class}" end def graphql_query(path: self.path, **kargs, &block) query_params = self.class.slice_params(kargs) request(*path) do client.query(query_params, &block) end rescue Faraday::ParsingError => e puts "Internal Error with these params:" pp kargs raise end def request(*path) response = yield wrap_response(response, path) end def wrap_response(response, path = []) raise "Complete failure on request. Path: #{path}" unless res = response.to_h.dig(*path.dup.unshift("data")) data = Ecoportal::API::Common::GraphQL::HashHelpers.deep_dup(res) response_class.new(data) end end end end end end