graphql 1.10.1 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +18 -2
- data/lib/generators/graphql/install_generator.rb +36 -6
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +2 -1
- data/lib/generators/graphql/object_generator.rb +54 -9
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/interface.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +3 -1
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +21 -33
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +24 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +126 -109
- data/lib/graphql/analysis/ast/visitor.rb +13 -5
- data/lib/graphql/analysis/ast.rb +11 -2
- data/lib/graphql/argument.rb +3 -3
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +34 -3
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +40 -9
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- data/lib/graphql/compatibility/execution_specification.rb +1 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/instance_definable.rb +34 -4
- data/lib/graphql/define/type_definer.rb +5 -5
- data/lib/graphql/deprecated_dsl.rb +18 -5
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/directive.rb +4 -4
- data/lib/graphql/enum_type.rb +7 -1
- data/lib/graphql/execution/errors.rb +110 -7
- data/lib/graphql/execution/execute.rb +8 -1
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +103 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +685 -421
- data/lib/graphql/execution/interpreter.rb +42 -13
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +25 -110
- data/lib/graphql/execution/multiplex.rb +37 -25
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/function.rb +4 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +7 -0
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +8 -4
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +4 -4
- data/lib/graphql/introspection/type_type.rb +16 -12
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +73 -25
- data/lib/graphql/language/lexer.rb +4 -3
- data/lib/graphql/language/lexer.rl +3 -3
- data/lib/graphql/language/nodes.rb +51 -89
- data/lib/graphql/language/parser.rb +552 -530
- data/lib/graphql/language/parser.y +114 -99
- data/lib/graphql/language/printer.rb +7 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/object_type.rb +44 -35
- data/lib/graphql/pagination/active_record_relation_connection.rb +14 -1
- data/lib/graphql/pagination/array_connection.rb +2 -2
- data/lib/graphql/pagination/connection.rb +75 -20
- data/lib/graphql/pagination/connections.rb +83 -31
- data/lib/graphql/pagination/relation_connection.rb +34 -14
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +4 -3
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +42 -7
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/serial_execution.rb +1 -0
- data/lib/graphql/query/validation_pipeline.rb +5 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +14 -4
- data/lib/graphql/query.rb +68 -13
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +26 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/mutation.rb +1 -0
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/range_add.rb +23 -9
- data/lib/graphql/relay/relation_connection.rb +8 -10
- data/lib/graphql/relay/type_extensions.rb +2 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/scalar_type.rb +16 -1
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +210 -12
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +213 -86
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +78 -2
- data/lib/graphql/schema/enum.rb +80 -9
- data/lib/graphql/schema/enum_value.rb +17 -6
- data/lib/graphql/schema/field/connection_extension.rb +46 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +285 -133
- data/lib/graphql/schema/find_inherited_value.rb +4 -1
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +97 -89
- data/lib/graphql/schema/interface.rb +24 -19
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +7 -1
- data/lib/graphql/schema/loader.rb +137 -103
- data/lib/graphql/schema/member/accepts_definition.rb +8 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -19
- data/lib/graphql/schema/member/build_type.rb +14 -7
- data/lib/graphql/schema/member/has_arguments.rb +205 -12
- data/lib/graphql/schema/member/has_ast_node.rb +4 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +95 -30
- data/lib/graphql/schema/member/has_interfaces.rb +90 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/instrumentation.rb +0 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/non_null.rb +5 -0
- data/lib/graphql/schema/object.rb +47 -46
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +32 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +123 -63
- data/lib/graphql/schema/scalar.rb +11 -1
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/timeout_middleware.rb +3 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +41 -1
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +12 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +68 -0
- data/lib/graphql/schema/validator.rb +174 -0
- data/lib/graphql/schema/warden.rb +153 -28
- data/lib/graphql/schema.rb +364 -330
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +8 -5
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +79 -43
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +8 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +9 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +42 -8
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +118 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +81 -30
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +33 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -4
- data/lib/graphql/subscriptions.rb +88 -45
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/platform_tracing.rb +43 -17
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +9 -33
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +3 -3
- data/lib/graphql/types/iso_8601_date_time.rb +25 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +53 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +15 -0
- data/lib/graphql/types/relay/node_field.rb +2 -20
- data/lib/graphql/types/relay/nodes_field.rb +2 -20
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -3
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/union_type.rb +2 -0
- data/lib/graphql/upgrader/member.rb +1 -0
- data/lib/graphql/upgrader/schema.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +65 -31
- data/readme.md +3 -6
- metadata +77 -112
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
@@ -5,23 +5,17 @@ module GraphQL
|
|
5
5
|
class Schema
|
6
6
|
module BuildFromDefinition
|
7
7
|
class << self
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# @see {Schema.from_definition}
|
9
|
+
def from_definition(definition_string, parser: GraphQL.default_parser, **kwargs)
|
10
|
+
from_document(parser.parse(definition_string), **kwargs)
|
11
11
|
end
|
12
|
-
end
|
13
12
|
|
14
|
-
|
15
|
-
|
13
|
+
def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
|
14
|
+
from_document(parser.parse_file(definition_path), **kwargs)
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
def self.call(type, field, obj, args, ctx)
|
20
|
-
if field.arguments.any?
|
21
|
-
obj.public_send(field.name, args, ctx)
|
22
|
-
else
|
23
|
-
obj.public_send(field.name)
|
24
|
-
end
|
17
|
+
def from_document(document, default_resolve:, using: {}, relay: false)
|
18
|
+
Builder.build(document, default_resolve: default_resolve || {}, relay: relay, using: using)
|
25
19
|
end
|
26
20
|
end
|
27
21
|
|
@@ -29,7 +23,7 @@ module GraphQL
|
|
29
23
|
module Builder
|
30
24
|
extend self
|
31
25
|
|
32
|
-
def build(document, default_resolve
|
26
|
+
def build(document, default_resolve:, using: {}, relay:)
|
33
27
|
raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
|
34
28
|
|
35
29
|
if default_resolve.is_a?(Hash)
|
@@ -42,34 +36,50 @@ module GraphQL
|
|
42
36
|
end
|
43
37
|
schema_definition = schema_defns.first
|
44
38
|
types = {}
|
45
|
-
types.merge!(GraphQL::Schema::BUILT_IN_TYPES)
|
46
39
|
directives = {}
|
47
|
-
type_resolver = ->(
|
40
|
+
type_resolver = build_resolve_type(types, directives, ->(type_name) { types[type_name] ||= Schema::LateBoundType.new(type_name)})
|
41
|
+
# Make a different type resolver because we need to coerce directive arguments
|
42
|
+
# _while_ building the schema.
|
43
|
+
# It will dig for a type if it encounters a custom type. This could be a problem if there are cycles.
|
44
|
+
directive_type_resolver = nil
|
45
|
+
directive_type_resolver = build_resolve_type(types, directives, ->(type_name) {
|
46
|
+
types[type_name] ||= begin
|
47
|
+
defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
|
48
|
+
if defn
|
49
|
+
build_definition_from_node(defn, directive_type_resolver, default_resolve)
|
50
|
+
elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
|
51
|
+
built_in_defn
|
52
|
+
else
|
53
|
+
raise "No definition for #{type_name.inspect} found in schema document or built-in types. Add a definition for it or remove it."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
})
|
57
|
+
|
58
|
+
document.definitions.each do |definition|
|
59
|
+
if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
|
60
|
+
directives[definition.name] = build_directive(definition, directive_type_resolver)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
directives = GraphQL::Schema.default_directives.merge(directives)
|
65
|
+
|
66
|
+
# In case any directives referenced built-in types for their arguments:
|
67
|
+
replace_late_bound_types_with_built_in(types)
|
48
68
|
|
49
69
|
document.definitions.each do |definition|
|
50
70
|
case definition
|
51
|
-
when GraphQL::Language::Nodes::SchemaDefinition
|
71
|
+
when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
|
52
72
|
nil # already handled
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
60
|
-
types[definition.name] = build_interface_type(definition, type_resolver)
|
61
|
-
when GraphQL::Language::Nodes::UnionTypeDefinition
|
62
|
-
types[definition.name] = build_union_type(definition, type_resolver)
|
63
|
-
when GraphQL::Language::Nodes::ScalarTypeDefinition
|
64
|
-
types[definition.name] = build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
|
65
|
-
when GraphQL::Language::Nodes::InputObjectTypeDefinition
|
66
|
-
types[definition.name] = build_input_object_type(definition, type_resolver)
|
67
|
-
when GraphQL::Language::Nodes::DirectiveDefinition
|
68
|
-
directives[definition.name] = build_directive(definition, type_resolver)
|
73
|
+
else
|
74
|
+
# It's possible that this was already loaded by the directives
|
75
|
+
prev_type = types[definition.name]
|
76
|
+
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
|
77
|
+
types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve)
|
78
|
+
end
|
69
79
|
end
|
70
80
|
end
|
71
81
|
|
72
|
-
|
82
|
+
replace_late_bound_types_with_built_in(types)
|
73
83
|
|
74
84
|
if schema_definition
|
75
85
|
if schema_definition.query
|
@@ -108,11 +118,11 @@ module GraphQL
|
|
108
118
|
end
|
109
119
|
|
110
120
|
if default_resolve.respond_to?(:resolve_type)
|
111
|
-
|
112
|
-
|
121
|
+
def self.resolve_type(*args)
|
122
|
+
self.definition_default_resolve.resolve_type(*args)
|
113
123
|
end
|
114
124
|
else
|
115
|
-
|
125
|
+
def self.resolve_type(*args)
|
116
126
|
NullResolveType.call(*args)
|
117
127
|
end
|
118
128
|
end
|
@@ -123,11 +133,6 @@ module GraphQL
|
|
123
133
|
ast_node(schema_definition)
|
124
134
|
end
|
125
135
|
|
126
|
-
if interpreter
|
127
|
-
use GraphQL::Execution::Interpreter
|
128
|
-
use GraphQL::Analysis::AST
|
129
|
-
end
|
130
|
-
|
131
136
|
using.each do |plugin, options|
|
132
137
|
if options
|
133
138
|
use(plugin, **options)
|
@@ -135,6 +140,23 @@ module GraphQL
|
|
135
140
|
use(plugin)
|
136
141
|
end
|
137
142
|
end
|
143
|
+
|
144
|
+
# Empty `orphan_types` -- this will make unreachable types ... unreachable.
|
145
|
+
own_orphan_types.clear
|
146
|
+
|
147
|
+
class << self
|
148
|
+
attr_accessor :definition_default_resolve
|
149
|
+
end
|
150
|
+
|
151
|
+
self.definition_default_resolve = default_resolve
|
152
|
+
|
153
|
+
def definition_default_resolve
|
154
|
+
self.class.definition_default_resolve
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.inherited(child_class)
|
158
|
+
child_class.definition_default_resolve = self.definition_default_resolve
|
159
|
+
end
|
138
160
|
end
|
139
161
|
end
|
140
162
|
|
@@ -142,10 +164,85 @@ module GraphQL
|
|
142
164
|
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
|
143
165
|
}
|
144
166
|
|
167
|
+
def build_definition_from_node(definition, type_resolver, default_resolve)
|
168
|
+
case definition
|
169
|
+
when GraphQL::Language::Nodes::EnumTypeDefinition
|
170
|
+
build_enum_type(definition, type_resolver)
|
171
|
+
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
172
|
+
build_object_type(definition, type_resolver)
|
173
|
+
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
174
|
+
build_interface_type(definition, type_resolver)
|
175
|
+
when GraphQL::Language::Nodes::UnionTypeDefinition
|
176
|
+
build_union_type(definition, type_resolver)
|
177
|
+
when GraphQL::Language::Nodes::ScalarTypeDefinition
|
178
|
+
build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
|
179
|
+
when GraphQL::Language::Nodes::InputObjectTypeDefinition
|
180
|
+
build_input_object_type(definition, type_resolver)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Modify `types`, replacing any late-bound references to built-in types
|
185
|
+
# with their actual definitions.
|
186
|
+
#
|
187
|
+
# (Schema definitions are allowed to reference those built-ins without redefining them.)
|
188
|
+
# @return void
|
189
|
+
def replace_late_bound_types_with_built_in(types)
|
190
|
+
GraphQL::Schema::BUILT_IN_TYPES.each do |scalar_name, built_in_scalar|
|
191
|
+
existing_type = types[scalar_name]
|
192
|
+
if existing_type.is_a?(GraphQL::Schema::LateBoundType)
|
193
|
+
types[scalar_name] = built_in_scalar
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def build_directives(definition, ast_node, type_resolver)
|
199
|
+
dirs = prepare_directives(ast_node, type_resolver)
|
200
|
+
dirs.each do |dir_class, options|
|
201
|
+
definition.directive(dir_class, **options)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def prepare_directives(ast_node, type_resolver)
|
206
|
+
dirs = {}
|
207
|
+
ast_node.directives.each do |dir_node|
|
208
|
+
if dir_node.name == "deprecated"
|
209
|
+
# This is handled using `deprecation_reason`
|
210
|
+
next
|
211
|
+
else
|
212
|
+
dir_class = type_resolver.call(dir_node.name)
|
213
|
+
if dir_class.nil?
|
214
|
+
raise ArgumentError, "No definition for @#{dir_node.name} on #{ast_node.name} at #{ast_node.line}:#{ast_node.col}"
|
215
|
+
end
|
216
|
+
options = args_to_kwargs(dir_class, dir_node)
|
217
|
+
dirs[dir_class] = options
|
218
|
+
end
|
219
|
+
end
|
220
|
+
dirs
|
221
|
+
end
|
222
|
+
|
223
|
+
def args_to_kwargs(arg_owner, node)
|
224
|
+
if node.respond_to?(:arguments)
|
225
|
+
kwargs = {}
|
226
|
+
node.arguments.each do |arg_node|
|
227
|
+
arg_defn = arg_owner.get_argument(arg_node.name)
|
228
|
+
kwargs[arg_defn.keyword] = args_to_kwargs(arg_defn.type.unwrap, arg_node.value)
|
229
|
+
end
|
230
|
+
kwargs
|
231
|
+
elsif node.is_a?(Array)
|
232
|
+
node.map { |n| args_to_kwargs(arg_owner, n) }
|
233
|
+
elsif node.is_a?(Language::Nodes::Enum)
|
234
|
+
node.name
|
235
|
+
else
|
236
|
+
# scalar
|
237
|
+
node
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
145
241
|
def build_enum_type(enum_type_definition, type_resolver)
|
146
242
|
builder = self
|
147
243
|
Class.new(GraphQL::Schema::Enum) do
|
148
244
|
graphql_name(enum_type_definition.name)
|
245
|
+
builder.build_directives(self, enum_type_definition, type_resolver)
|
149
246
|
description(enum_type_definition.description)
|
150
247
|
ast_node(enum_type_definition)
|
151
248
|
enum_type_definition.values.each do |enum_value_definition|
|
@@ -153,6 +250,7 @@ module GraphQL
|
|
153
250
|
value: enum_value_definition.name,
|
154
251
|
deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
|
155
252
|
description: enum_value_definition.description,
|
253
|
+
directives: builder.prepare_directives(enum_value_definition, type_resolver),
|
156
254
|
ast_node: enum_value_definition,
|
157
255
|
)
|
158
256
|
end
|
@@ -170,53 +268,54 @@ module GraphQL
|
|
170
268
|
end
|
171
269
|
|
172
270
|
def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
|
271
|
+
builder = self
|
173
272
|
Class.new(GraphQL::Schema::Scalar) do
|
174
273
|
graphql_name(scalar_type_definition.name)
|
175
274
|
description(scalar_type_definition.description)
|
176
275
|
ast_node(scalar_type_definition)
|
276
|
+
builder.build_directives(self, scalar_type_definition, type_resolver)
|
177
277
|
|
178
278
|
if default_resolve.respond_to?(:coerce_input)
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
define_singleton_method(:coerce_result) do |val, ctx|
|
184
|
-
default_resolve.coerce_result(self, val, ctx)
|
185
|
-
end
|
279
|
+
# Put these method definitions in another method to avoid retaining `type_resolve`
|
280
|
+
# from this method's bindiing
|
281
|
+
builder.build_scalar_type_coerce_method(self, :coerce_input, default_resolve)
|
282
|
+
builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
|
186
283
|
end
|
187
284
|
end
|
188
285
|
end
|
189
286
|
|
287
|
+
def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
|
288
|
+
scalar_class.define_singleton_method(method_name) do |val, ctx|
|
289
|
+
default_definition_resolve.public_send(method_name, self, val, ctx)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
190
293
|
def build_union_type(union_type_definition, type_resolver)
|
294
|
+
builder = self
|
191
295
|
Class.new(GraphQL::Schema::Union) do
|
192
296
|
graphql_name(union_type_definition.name)
|
193
297
|
description(union_type_definition.description)
|
194
298
|
possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
|
195
299
|
ast_node(union_type_definition)
|
300
|
+
builder.build_directives(self, union_type_definition, type_resolver)
|
196
301
|
end
|
197
302
|
end
|
198
303
|
|
199
|
-
def build_object_type(object_type_definition, type_resolver
|
304
|
+
def build_object_type(object_type_definition, type_resolver)
|
200
305
|
builder = self
|
201
|
-
type_def = nil
|
202
|
-
typed_resolve_fn = ->(field, obj, args, ctx) { default_resolve.call(type_def, field, obj, args, ctx) }
|
203
306
|
|
204
307
|
Class.new(GraphQL::Schema::Object) do
|
205
|
-
type_def = self
|
206
308
|
graphql_name(object_type_definition.name)
|
207
309
|
description(object_type_definition.description)
|
208
310
|
ast_node(object_type_definition)
|
209
|
-
|
210
|
-
# This has to come before `field ...` configurations since it modifies them
|
211
|
-
extend Subscriptions::SubscriptionRoot
|
212
|
-
end
|
311
|
+
builder.build_directives(self, object_type_definition, type_resolver)
|
213
312
|
|
214
313
|
object_type_definition.interfaces.each do |interface_name|
|
215
314
|
interface_defn = type_resolver.call(interface_name)
|
216
315
|
implements(interface_defn)
|
217
316
|
end
|
218
317
|
|
219
|
-
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve:
|
318
|
+
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
220
319
|
end
|
221
320
|
end
|
222
321
|
|
@@ -226,6 +325,7 @@ module GraphQL
|
|
226
325
|
graphql_name(input_object_type_definition.name)
|
227
326
|
description(input_object_type_definition.description)
|
228
327
|
ast_node(input_object_type_definition)
|
328
|
+
builder.build_directives(self, input_object_type_definition, type_resolver)
|
229
329
|
builder.build_arguments(self, input_object_type_definition.fields, type_resolver)
|
230
330
|
end
|
231
331
|
end
|
@@ -245,13 +345,16 @@ module GraphQL
|
|
245
345
|
end
|
246
346
|
end
|
247
347
|
|
348
|
+
NO_DEFAULT_VALUE = {}.freeze
|
349
|
+
|
248
350
|
def build_arguments(type_class, arguments, type_resolver)
|
249
351
|
builder = self
|
250
352
|
|
251
353
|
arguments.each do |argument_defn|
|
252
|
-
default_value_kwargs =
|
253
|
-
|
254
|
-
|
354
|
+
default_value_kwargs = if !argument_defn.default_value.nil?
|
355
|
+
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
356
|
+
else
|
357
|
+
NO_DEFAULT_VALUE
|
255
358
|
end
|
256
359
|
|
257
360
|
type_class.argument(
|
@@ -259,9 +362,11 @@ module GraphQL
|
|
259
362
|
type: type_resolver.call(argument_defn.type),
|
260
363
|
required: false,
|
261
364
|
description: argument_defn.description,
|
365
|
+
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
262
366
|
ast_node: argument_defn,
|
263
367
|
camelize: false,
|
264
368
|
method_access: false,
|
369
|
+
directives: prepare_directives(argument_defn, type_resolver),
|
265
370
|
**default_value_kwargs
|
266
371
|
)
|
267
372
|
end
|
@@ -284,7 +389,13 @@ module GraphQL
|
|
284
389
|
include GraphQL::Schema::Interface
|
285
390
|
graphql_name(interface_type_definition.name)
|
286
391
|
description(interface_type_definition.description)
|
392
|
+
interface_type_definition.interfaces.each do |interface_name|
|
393
|
+
"Implements: #{interface_type_definition} -> #{interface_name}"
|
394
|
+
interface_defn = type_resolver.call(interface_name)
|
395
|
+
implements(interface_defn)
|
396
|
+
end
|
287
397
|
ast_node(interface_type_definition)
|
398
|
+
builder.build_directives(self, interface_type_definition, type_resolver)
|
288
399
|
|
289
400
|
builder.build_fields(self, interface_type_definition.fields, type_resolver, default_resolve: nil)
|
290
401
|
end
|
@@ -293,45 +404,61 @@ module GraphQL
|
|
293
404
|
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
|
294
405
|
builder = self
|
295
406
|
|
296
|
-
field_definitions.
|
407
|
+
field_definitions.each do |field_definition|
|
297
408
|
type_name = resolve_type_name(field_definition.type)
|
298
|
-
|
299
|
-
owner.field(
|
409
|
+
resolve_method_name = -"resolve_field_#{field_definition.name}"
|
410
|
+
schema_field_defn = owner.field(
|
300
411
|
field_definition.name,
|
301
412
|
description: field_definition.description,
|
302
413
|
type: type_resolver.call(field_definition.type),
|
303
414
|
null: true,
|
304
415
|
connection: type_name.end_with?("Connection"),
|
416
|
+
connection_extension: nil,
|
305
417
|
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
306
418
|
ast_node: field_definition,
|
307
419
|
method_conflict_warning: false,
|
308
420
|
camelize: false,
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
421
|
+
directives: prepare_directives(field_definition, type_resolver),
|
422
|
+
resolver_method: resolve_method_name,
|
423
|
+
)
|
424
|
+
|
425
|
+
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
426
|
+
|
427
|
+
# Don't do this for interfaces
|
428
|
+
if default_resolve
|
429
|
+
owner.class_eval <<-RUBY, __FILE__, __LINE__
|
430
|
+
# frozen_string_literal: true
|
431
|
+
def #{resolve_method_name}(**args)
|
432
|
+
field_instance = self.class.get_field("#{field_definition.name}")
|
433
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
317
434
|
end
|
318
|
-
|
435
|
+
RUBY
|
319
436
|
end
|
320
437
|
end
|
321
438
|
end
|
322
439
|
|
323
|
-
def
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
440
|
+
def build_resolve_type(lookup_hash, directives, missing_type_handler)
|
441
|
+
resolve_type_proc = nil
|
442
|
+
resolve_type_proc = ->(ast_node) {
|
443
|
+
case ast_node
|
444
|
+
when GraphQL::Language::Nodes::TypeName
|
445
|
+
type_name = ast_node.name
|
446
|
+
if lookup_hash.key?(type_name)
|
447
|
+
lookup_hash[type_name]
|
448
|
+
else
|
449
|
+
missing_type_handler.call(type_name)
|
450
|
+
end
|
451
|
+
when GraphQL::Language::Nodes::NonNullType
|
452
|
+
resolve_type_proc.call(ast_node.of_type).to_non_null_type
|
453
|
+
when GraphQL::Language::Nodes::ListType
|
454
|
+
resolve_type_proc.call(ast_node.of_type).to_list_type
|
455
|
+
when String
|
456
|
+
directives[ast_node]
|
457
|
+
else
|
458
|
+
raise "Unexpected ast_node: #{ast_node.inspect}"
|
459
|
+
end
|
460
|
+
}
|
461
|
+
resolve_type_proc
|
335
462
|
end
|
336
463
|
|
337
464
|
def resolve_type_name(type)
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
class Directive < GraphQL::Schema::Member
|
5
5
|
class Deprecated < GraphQL::Schema::Directive
|
6
6
|
description "Marks an element of a GraphQL schema as no longer supported."
|
7
|
-
locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE)
|
7
|
+
locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE, GraphQL::Schema::Directive::ARGUMENT_DEFINITION, GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION)
|
8
8
|
|
9
9
|
reason_description = "Explains why this element was deprecated, usually also including a "\
|
10
10
|
"suggestion for how to access supported similar data. Formatted "\
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
# This is _similar_ to {Directive::Feature}, except it's prescribed by the server, not the client.
|
6
|
+
#
|
7
|
+
# In this case, the server hides types and fields _entirely_, unless the current context has certain `:flags` present.
|
8
|
+
class Flagged < GraphQL::Schema::Directive
|
9
|
+
def initialize(target, **options)
|
10
|
+
if target.is_a?(Module) && !target.ancestors.include?(VisibleByFlag)
|
11
|
+
# This is type class of some kind, `include` will put this module
|
12
|
+
# in between the type class itself and its super class, so `super` will work fine
|
13
|
+
target.include(VisibleByFlag)
|
14
|
+
elsif !target.is_a?(VisibleByFlag)
|
15
|
+
# This is an instance of a base class. `include` won't put this in front of the
|
16
|
+
# base class implementation, so we need to `.prepend`.
|
17
|
+
# `#visible?` could probably be moved to a module and then this could use `include` instead.
|
18
|
+
target.class.prepend(VisibleByFlag)
|
19
|
+
end
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
description "Hides this part of the schema unless the named flag is present in context[:flags]"
|
24
|
+
|
25
|
+
locations(
|
26
|
+
GraphQL::Schema::Directive::FIELD_DEFINITION,
|
27
|
+
GraphQL::Schema::Directive::OBJECT,
|
28
|
+
GraphQL::Schema::Directive::SCALAR,
|
29
|
+
GraphQL::Schema::Directive::ENUM,
|
30
|
+
GraphQL::Schema::Directive::UNION,
|
31
|
+
GraphQL::Schema::Directive::INTERFACE,
|
32
|
+
GraphQL::Schema::Directive::INPUT_OBJECT,
|
33
|
+
GraphQL::Schema::Directive::ENUM_VALUE,
|
34
|
+
GraphQL::Schema::Directive::ARGUMENT_DEFINITION,
|
35
|
+
GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION,
|
36
|
+
)
|
37
|
+
|
38
|
+
argument :by, [String], "Flags to check for this schema member"
|
39
|
+
|
40
|
+
module VisibleByFlag
|
41
|
+
def self.included(schema_class)
|
42
|
+
schema_class.extend(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def visible?(context)
|
46
|
+
if dir = self.directives.find { |d| d.is_a?(Flagged) }
|
47
|
+
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
48
|
+
relevant_flags && relevant_flags.any? && super
|
49
|
+
else
|
50
|
+
super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -24,7 +24,7 @@ module GraphQL
|
|
24
24
|
GraphQL::Schema::Directive::FIELD,
|
25
25
|
)
|
26
26
|
|
27
|
-
argument :by, String,
|
27
|
+
argument :by, String,
|
28
28
|
description: "The name of the transform to run if applicable"
|
29
29
|
|
30
30
|
TRANSFORMS = [
|
@@ -39,7 +39,19 @@ module GraphQL
|
|
39
39
|
transform_name = arguments[:by]
|
40
40
|
if TRANSFORMS.include?(transform_name) && return_value.respond_to?(transform_name)
|
41
41
|
return_value = return_value.public_send(transform_name)
|
42
|
-
context.namespace(:interpreter)[:runtime].
|
42
|
+
response = context.namespace(:interpreter)[:runtime].final_result
|
43
|
+
*keys, last = path
|
44
|
+
keys.each do |key|
|
45
|
+
if response && (response = response[key])
|
46
|
+
next
|
47
|
+
else
|
48
|
+
break
|
49
|
+
end
|
50
|
+
end
|
51
|
+
if response
|
52
|
+
response[last] = return_value
|
53
|
+
end
|
54
|
+
nil
|
43
55
|
end
|
44
56
|
end
|
45
57
|
end
|