Class: ElasticGraph::GraphQL::Schema::Type
- Inherits:
-
Object
- Object
- ElasticGraph::GraphQL::Schema::Type
- Extended by:
- Forwardable
- Defined in:
- lib/elastic_graph/graphql/schema/type.rb
Overview
Represents a GraphQL type.
Instance Attribute Summary collapse
-
#elasticgraph_category ⇒ Object
readonly
Returns the value of attribute elasticgraph_category.
-
#fields_by_name ⇒ Object
readonly
Returns the value of attribute fields_by_name.
-
#graphql_only_return_type ⇒ Object
readonly
Returns the value of attribute graphql_only_return_type.
-
#graphql_type ⇒ Object
readonly
Returns the value of attribute graphql_type.
-
#index_definitions ⇒ Object
readonly
Returns the value of attribute index_definitions.
Instance Method Summary collapse
- #abstract? ⇒ Boolean
- #coerce_result(result) ⇒ Object
- #collection? ⇒ Boolean
-
#embedded_object? ⇒ Boolean
Indicates if this type is an object type that is embedded in another indexed type in the index mapping.
- #enum? ⇒ Boolean
- #enum_value_named(enum_value_name) ⇒ Object
- #field_named(field_name) ⇒ Object
-
#hidden_from_queries? ⇒ Boolean
Indicates this type should be hidden in the GraphQL schema so as to not be queryable.
- #indexed_aggregation? ⇒ Boolean
-
#indexed_document? ⇒ Boolean
Is the type a user-defined document type directly indexed in the index?.
-
#initialize(schema, graphql_type, index_definitions, object_runtime_metadata, enum_runtime_metadata) ⇒ Type
constructor
A new instance of Type.
- #name ⇒ Object
- #nullable? ⇒ Boolean
-
#object? ⇒ Boolean
Returns ‘true` if this type serializes as a JSON object, with sub-fields.
- #relay_connection? ⇒ Boolean
- #relay_edge? ⇒ Boolean
-
#search_index_definitions ⇒ Object
(also: #indexing_index_definitions)
List of index definitions that should be searched for this type.
-
#subtypes ⇒ Object
Returns the subtypes of this type, if it has any.
- #to_s ⇒ Object (also: #inspect)
-
#unwrap_fully ⇒ Object
Fully unwraps this type, in order to extracts the underlying type (an object or scalar) from its wrappings.
-
#unwrap_non_null ⇒ Object
Unwraps the non-null type wrapping, if this type is non-null.
Constructor Details
#initialize(schema, graphql_type, index_definitions, object_runtime_metadata, enum_runtime_metadata) ⇒ Type
Returns a new instance of Type.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 22 def initialize( schema, graphql_type, index_definitions, , ) @schema = schema @graphql_type = graphql_type @enum_values_by_name = Hash.new do |hash, key| hash[key] = lookup_enum_value_by_name(key) end @index_definitions = index_definitions @object_runtime_metadata = @elasticgraph_category = &.elasticgraph_category @graphql_only_return_type = &.graphql_only_return_type @enum_runtime_metadata = @enum_value_names_by_original_name = (&.values_by_name || {}).to_h do |name, value| [value.alternate_original_name || name, name] end @fields_by_name = build_fields_by_name_hash(schema, graphql_type).freeze end |
Instance Attribute Details
#elasticgraph_category ⇒ Object (readonly)
Returns the value of attribute elasticgraph_category.
20 21 22 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 20 def elasticgraph_category @elasticgraph_category end |
#fields_by_name ⇒ Object (readonly)
Returns the value of attribute fields_by_name.
20 21 22 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 20 def fields_by_name @fields_by_name end |
#graphql_only_return_type ⇒ Object (readonly)
Returns the value of attribute graphql_only_return_type.
20 21 22 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 20 def graphql_only_return_type @graphql_only_return_type end |
#graphql_type ⇒ Object (readonly)
Returns the value of attribute graphql_type.
20 21 22 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 20 def graphql_type @graphql_type end |
#index_definitions ⇒ Object (readonly)
Returns the value of attribute index_definitions.
20 21 22 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 20 def index_definitions @index_definitions end |
Instance Method Details
#abstract? ⇒ Boolean
159 160 161 162 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 159 def abstract? return unwrap_non_null.abstract? if non_null? @graphql_type.kind.abstract? end |
#coerce_result(result) ⇒ Object
128 129 130 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 128 def coerce_result(result) @enum_value_names_by_original_name.fetch(result, result) end |
#collection? ⇒ Boolean
201 202 203 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 201 def collection? list? || relay_connection? end |
#embedded_object? ⇒ Boolean
Indicates if this type is an object type that is embedded in another indexed type in the index mapping. Note: we have avoided the term ‘nested` here because it is a specific Elasticsearch/OpenSearch mapping type that we will not necessarily be using: www.elastic.co/guide/en/elasticsearch/reference/current/nested.html
195 196 197 198 199 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 195 def return unwrap_non_null. if non_null? return false if relay_edge? || relay_connection? || @graphql_type.kind.input_object? object? && !indexed_document? && !indexed_aggregation? end |
#enum? ⇒ Boolean
164 165 166 167 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 164 def enum? return unwrap_non_null.enum? if non_null? @graphql_type.kind.enum? end |
#enum_value_named(enum_value_name) ⇒ Object
124 125 126 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 124 def enum_value_named(enum_value_name) @enum_values_by_name[enum_value_name.to_s] end |
#field_named(field_name) ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 116 def field_named(field_name) @fields_by_name.fetch(field_name.to_s) rescue KeyError => e msg = "No field named #{field_name} (on type #{name}) could be found" msg += "; Possible alternatives: [#{e.corrections.join(", ").delete('"')}]." if e.corrections.any? raise NotFoundError, msg end |
#hidden_from_queries? ⇒ Boolean
Indicates this type should be hidden in the GraphQL schema so as to not be queryable. We only hide a type if both of the following are true:
-
It’s backed by one or more search index definitions
-
None of the search index definitions are accessible from queries
218 219 220 221 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 218 def hidden_from_queries? return false if search_index_definitions.empty? search_index_definitions.none?(&:accessible_from_queries?) end |
#indexed_aggregation? ⇒ Boolean
187 188 189 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 187 def indexed_aggregation? unwrapped_has_category?(:indexed_aggregation) end |
#indexed_document? ⇒ Boolean
Is the type a user-defined document type directly indexed in the index?
180 181 182 183 184 185 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 180 def indexed_document? return unwrap_non_null.indexed_document? if non_null? return false if indexed_aggregation? return true if subtypes.any? && subtypes.all?(&:indexed_document?) @index_definitions.any? end |
#name ⇒ Object
47 48 49 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 47 def name @name ||= @graphql_type.to_type_signature.to_sym end |
#nullable? ⇒ Boolean
155 156 157 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 155 def nullable? !non_null? end |
#object? ⇒ Boolean
Returns ‘true` if this type serializes as a JSON object, with sub-fields. Note this is slightly different from the GraphQL gem and GraphQL spec: it considers inputs to be distinct from objects, but for our purposes we consider inputs to be objects since they have sub-fields and serialize as JSON objects.
173 174 175 176 177 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 173 def object? return unwrap_non_null.object? if non_null? kind = @graphql_type.kind kind.abstract? || kind.object? || kind.input_object? end |
#relay_connection? ⇒ Boolean
205 206 207 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 205 def relay_connection? unwrapped_has_category?(:relay_connection) end |
#relay_edge? ⇒ Boolean
209 210 211 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 209 def relay_edge? unwrapped_has_category?(:relay_edge) end |
#search_index_definitions ⇒ Object Also known as: indexing_index_definitions
List of index definitions that should be searched for this type.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 52 def search_index_definitions @search_index_definitions ||= if indexed_aggregation? # For an indexed aggregation, we just delegate to its source type. This works better than # dumping index definitions in the runtime metadata of the indexed aggregation type itself # because of abstract (interface/union) types. The source document type handles that (since # there is a supertype/subtype relationship on the document types) but that relationship # does not exist on the indexed aggregation. # # For example, assume we have these indexed document types: # - type Person {} # - type Company {} # - union Inventor = Person | Company # # We can go from `Inventor` to its subtypes to find the search indexes. However, `InventorAggregation` # is NOT a union of `PersonAggregation` and `CompanyAggregation`, so we can't do the same thing on the # indexed aggregation types. Delegating to the source type solves this case. @schema.type_named(@object_runtime_metadata.source_type).search_index_definitions else @index_definitions.union(subtypes.flat_map(&:search_index_definitions)) end end |
#subtypes ⇒ Object
Returns the subtypes of this type, if it has any. This is like ‘#possible_types` provided by the GraphQL gem, but that includes a type itself when you ask for the possible types of a non-abstract type.
112 113 114 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 112 def subtypes @subtypes ||= @schema.graphql_schema.possible_types(graphql_type).map { |t| @schema.type_from(t) } - [self] end |
#to_s ⇒ Object Also known as: inspect
132 133 134 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 132 def to_s "#<#{self.class.name} #{name}>" end |
#unwrap_fully ⇒ Object
Fully unwraps this type, in order to extracts the underlying type (an object or scalar) from its wrappings. As needed, this will unwrap any of these wrappings:
- non-null
- list
- relay connection
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 96 def unwrap_fully @unwrap_fully ||= begin unwrapped = @schema.type_from(@graphql_type.unwrap) if unwrapped.relay_connection? unwrapped .field_named(@schema.element_names.edges).type.unwrap_fully .field_named(@schema.element_names.node).type.unwrap_fully else unwrapped end end end |
#unwrap_non_null ⇒ Object
Unwraps the non-null type wrapping, if this type is non-null. If this type is nullable, returns it as-is.
85 86 87 88 |
# File 'lib/elastic_graph/graphql/schema/type.rb', line 85 def unwrap_non_null return self if nullable? @schema.type_from(@graphql_type.of_type) end |