graphql 2.6.12 → 2.6.14
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.
- checksums.yaml +4 -4
- data/.rdoc_options +4 -0
- data/lib/generators/graphql/core.rb +1 -0
- data/lib/generators/graphql/detailed_trace_generator.rb +1 -0
- data/lib/generators/graphql/enum_generator.rb +1 -0
- data/lib/generators/graphql/field_extractor.rb +1 -0
- data/lib/generators/graphql/input_generator.rb +1 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +1 -0
- data/lib/generators/graphql/install_generator.rb +1 -0
- data/lib/generators/graphql/interface_generator.rb +1 -0
- data/lib/generators/graphql/loader_generator.rb +8 -2
- data/lib/generators/graphql/mutation_create_generator.rb +8 -2
- data/lib/generators/graphql/mutation_delete_generator.rb +8 -2
- data/lib/generators/graphql/mutation_generator.rb +8 -2
- data/lib/generators/graphql/mutation_update_generator.rb +8 -2
- data/lib/generators/graphql/object_generator.rb +1 -0
- data/lib/generators/graphql/orm_mutations_base.rb +8 -2
- data/lib/generators/graphql/relay.rb +1 -0
- data/lib/generators/graphql/relay_generator.rb +1 -0
- data/lib/generators/graphql/scalar_generator.rb +1 -0
- data/lib/generators/graphql/type_generator.rb +38 -8
- data/lib/generators/graphql/union_generator.rb +1 -0
- data/lib/graphql/analysis/analyzer.rb +35 -9
- data/lib/graphql/analysis/field_usage.rb +1 -0
- data/lib/graphql/analysis/max_query_complexity.rb +3 -2
- data/lib/graphql/analysis/max_query_depth.rb +1 -0
- data/lib/graphql/analysis/query_complexity.rb +57 -20
- data/lib/graphql/analysis/query_depth.rb +17 -12
- data/lib/graphql/analysis/visitor.rb +79 -16
- data/lib/graphql/analysis.rb +23 -6
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/autoload.rb +30 -7
- data/lib/graphql/backtrace/table.rb +21 -5
- data/lib/graphql/backtrace/traced_error.rb +8 -3
- data/lib/graphql/backtrace.rb +14 -9
- data/lib/graphql/coercion_error.rb +1 -0
- data/lib/graphql/current.rb +44 -19
- data/lib/graphql/dashboard/application_controller.rb +1 -0
- data/lib/graphql/dashboard/detailed_traces.rb +1 -0
- data/lib/graphql/dashboard/installable.rb +1 -0
- data/lib/graphql/dashboard/landings_controller.rb +1 -0
- data/lib/graphql/dashboard/limiters.rb +1 -0
- data/lib/graphql/dashboard/operation_store.rb +1 -0
- data/lib/graphql/dashboard/statics_controller.rb +1 -0
- data/lib/graphql/dashboard/subscriptions.rb +1 -0
- data/lib/graphql/dashboard.rb +36 -22
- data/lib/graphql/dataloader/active_record_association_source.rb +1 -0
- data/lib/graphql/dataloader/active_record_source.rb +1 -0
- data/lib/graphql/dataloader/async_dataloader.rb +8 -7
- data/lib/graphql/dataloader/null_dataloader.rb +4 -3
- data/lib/graphql/dataloader/request.rb +8 -2
- data/lib/graphql/dataloader/request_all.rb +8 -2
- data/lib/graphql/dataloader/source.rb +127 -35
- data/lib/graphql/dataloader.rb +91 -42
- data/lib/graphql/date_encoding_error.rb +2 -1
- data/lib/graphql/dig.rb +12 -3
- data/lib/graphql/duration_encoding_error.rb +2 -1
- data/lib/graphql/execution/directive_checks.rb +8 -3
- data/lib/graphql/execution/errors.rb +20 -6
- data/lib/graphql/execution/field_resolve_step.rb +263 -161
- data/lib/graphql/execution/finalize.rb +12 -6
- data/lib/graphql/execution/input_values.rb +5 -2
- data/lib/graphql/execution/interpreter/argument_value.rb +17 -5
- data/lib/graphql/execution/interpreter/arguments.rb +24 -9
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -1
- data/lib/graphql/execution/interpreter/execution_errors.rb +1 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +1 -0
- data/lib/graphql/execution/interpreter/resolve.rb +18 -8
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +4 -1
- data/lib/graphql/execution/interpreter/runtime.rb +66 -23
- data/lib/graphql/execution/interpreter.rb +15 -6
- data/lib/graphql/execution/lazy/lazy_method_map.rb +21 -8
- data/lib/graphql/execution/lazy.rb +34 -10
- data/lib/graphql/execution/load_argument_step.rb +1 -0
- data/lib/graphql/execution/lookahead.rb +137 -54
- data/lib/graphql/execution/multiplex.rb +4 -4
- data/lib/graphql/execution/next.rb +7 -0
- data/lib/graphql/execution/prepare_object_step.rb +38 -13
- data/lib/graphql/execution/resolve_type_step.rb +2 -1
- data/lib/graphql/execution/runner.rb +9 -3
- data/lib/graphql/execution/selections_step.rb +3 -2
- data/lib/graphql/execution.rb +2 -2
- data/lib/graphql/execution_error.rb +19 -10
- data/lib/graphql/float_decoding_error.rb +1 -0
- data/lib/graphql/float_encoding_error.rb +7 -2
- data/lib/graphql/integer_decoding_error.rb +2 -1
- data/lib/graphql/integer_encoding_error.rb +8 -3
- data/lib/graphql/introspection/base_object.rb +3 -1
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/dynamic_fields.rb +1 -0
- data/lib/graphql/introspection/entry_points.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/input_value_type.rb +1 -0
- data/lib/graphql/introspection/introspection_query.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +1 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/introspection.rb +1 -0
- data/lib/graphql/invalid_name_error.rb +1 -0
- data/lib/graphql/invalid_null_error.rb +19 -6
- data/lib/graphql/language/block_string.rb +2 -1
- data/lib/graphql/language/cache.rb +10 -4
- data/lib/graphql/language/comment.rb +1 -0
- data/lib/graphql/language/definition_slice.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +9 -10
- data/lib/graphql/language/generation.rb +23 -9
- data/lib/graphql/language/lexer.rb +6 -1
- data/lib/graphql/language/nodes.rb +2094 -419
- data/lib/graphql/language/parser.rb +22 -12
- data/lib/graphql/language/printer.rb +31 -16
- data/lib/graphql/language/sanitized_printer.rb +16 -5
- data/lib/graphql/language/static_visitor.rb +19 -4
- data/lib/graphql/language/visitor.rb +51 -29
- data/lib/graphql/language.rb +13 -7
- data/lib/graphql/load_application_object_failed_error.rb +14 -5
- data/lib/graphql/name_validator.rb +1 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +1 -0
- data/lib/graphql/pagination/array_connection.rb +20 -6
- data/lib/graphql/pagination/connection.rb +178 -48
- data/lib/graphql/pagination/connections.rb +21 -14
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -0
- data/lib/graphql/pagination/relation_connection.rb +137 -29
- data/lib/graphql/pagination/sequel_dataset_connection.rb +1 -0
- data/lib/graphql/pagination.rb +1 -0
- data/lib/graphql/parse_error.rb +1 -0
- data/lib/graphql/query/context/scoped_context.rb +2 -1
- data/lib/graphql/query/context.rb +106 -35
- data/lib/graphql/query/fingerprint.rb +15 -7
- data/lib/graphql/query/input_validation_result.rb +1 -0
- data/lib/graphql/query/null_context.rb +1 -0
- data/lib/graphql/query/partial.rb +28 -16
- data/lib/graphql/query/result.rb +15 -5
- data/lib/graphql/query/validation_pipeline.rb +16 -6
- data/lib/graphql/query/variable_validation_error.rb +1 -0
- data/lib/graphql/query/variables.rb +4 -1
- data/lib/graphql/query.rb +193 -49
- data/lib/graphql/railtie.rb +7 -3
- data/lib/graphql/rake_task/validate.rb +72 -17
- data/lib/graphql/rake_task.rb +55 -23
- data/lib/graphql/relay/range_add.rb +32 -21
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +9 -6
- data/lib/graphql/rubocop/graphql/default_required_true.rb +9 -6
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +12 -8
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +9 -5
- data/lib/graphql/rubocop.rb +1 -0
- data/lib/graphql/runtime_error.rb +1 -0
- data/lib/graphql/runtime_type_error.rb +1 -0
- data/lib/graphql/schema/addition.rb +69 -50
- data/lib/graphql/schema/always_visible.rb +1 -0
- data/lib/graphql/schema/argument.rb +279 -45
- data/lib/graphql/schema/base_64_encoder.rb +2 -2
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/build_from_definition.rb +507 -178
- data/lib/graphql/schema/built_in_types.rb +1 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -0
- data/lib/graphql/schema/directive/feature.rb +39 -22
- data/lib/graphql/schema/directive/flagged.rb +6 -1
- data/lib/graphql/schema/directive/include.rb +1 -0
- data/lib/graphql/schema/directive/one_of.rb +1 -0
- data/lib/graphql/schema/directive/skip.rb +1 -0
- data/lib/graphql/schema/directive/specified_by.rb +1 -0
- data/lib/graphql/schema/directive/transform.rb +17 -8
- data/lib/graphql/schema/directive.rb +28 -7
- data/lib/graphql/schema/enum.rb +99 -38
- data/lib/graphql/schema/enum_value.rb +21 -13
- data/lib/graphql/schema/field/connection_extension.rb +10 -2
- data/lib/graphql/schema/field/scope_extension.rb +1 -0
- data/lib/graphql/schema/field.rb +622 -110
- data/lib/graphql/schema/field_extension.rb +89 -34
- data/lib/graphql/schema/find_inherited_value.rb +5 -3
- data/lib/graphql/schema/finder.rb +22 -8
- data/lib/graphql/schema/has_single_input_argument.rb +39 -6
- data/lib/graphql/schema/input_object.rb +40 -13
- data/lib/graphql/schema/interface.rb +33 -17
- data/lib/graphql/schema/introspection_system.rb +7 -3
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +15 -4
- data/lib/graphql/schema/loader.rb +23 -12
- data/lib/graphql/schema/member/base_dsl_methods.rb +58 -12
- data/lib/graphql/schema/member/build_type.rb +21 -7
- data/lib/graphql/schema/member/graphql_type_names.rb +10 -6
- data/lib/graphql/schema/member/has_arguments.rb +111 -48
- data/lib/graphql/schema/member/has_ast_node.rb +1 -0
- data/lib/graphql/schema/member/has_authorization.rb +5 -0
- data/lib/graphql/schema/member/has_dataloader.rb +91 -34
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -2
- data/lib/graphql/schema/member/has_directives.rb +45 -11
- data/lib/graphql/schema/member/has_fields.rb +151 -70
- data/lib/graphql/schema/member/has_interfaces.rb +8 -2
- data/lib/graphql/schema/member/has_path.rb +14 -5
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +1 -0
- data/lib/graphql/schema/member/has_validators.rb +19 -4
- data/lib/graphql/schema/member/relay_shortcuts.rb +10 -2
- data/lib/graphql/schema/member/scoped.rb +14 -3
- data/lib/graphql/schema/member/type_system_helpers.rb +36 -6
- data/lib/graphql/schema/member/validates_input.rb +1 -0
- data/lib/graphql/schema/member.rb +9 -2
- data/lib/graphql/schema/mutation.rb +50 -46
- data/lib/graphql/schema/non_null.rb +21 -5
- data/lib/graphql/schema/object.rb +44 -15
- data/lib/graphql/schema/printer.rb +52 -31
- data/lib/graphql/schema/ractor_shareable.rb +6 -2
- data/lib/graphql/schema/relay_classic_mutation.rb +3 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +29 -7
- data/lib/graphql/schema/resolver.rb +156 -45
- data/lib/graphql/schema/scalar.rb +1 -0
- data/lib/graphql/schema/subscription.rb +67 -28
- data/lib/graphql/schema/timeout.rb +65 -25
- data/lib/graphql/schema/type_expression.rb +14 -5
- data/lib/graphql/schema/type_membership.rb +29 -10
- data/lib/graphql/schema/union.rb +4 -2
- data/lib/graphql/schema/unique_within_type.rb +24 -5
- data/lib/graphql/schema/validator/all_validator.rb +17 -9
- data/lib/graphql/schema/validator/allow_blank_validator.rb +8 -2
- data/lib/graphql/schema/validator/allow_null_validator.rb +8 -2
- data/lib/graphql/schema/validator/exclusion_validator.rb +14 -5
- data/lib/graphql/schema/validator/format_validator.rb +21 -10
- data/lib/graphql/schema/validator/inclusion_validator.rb +15 -6
- data/lib/graphql/schema/validator/length_validator.rb +23 -12
- data/lib/graphql/schema/validator/numericality_validator.rb +29 -16
- data/lib/graphql/schema/validator/required_validator.rb +45 -31
- data/lib/graphql/schema/validator.rb +89 -25
- data/lib/graphql/schema/visibility/migration.rb +14 -7
- data/lib/graphql/schema/visibility/profile.rb +20 -17
- data/lib/graphql/schema/visibility/visit.rb +12 -10
- data/lib/graphql/schema/visibility.rb +24 -20
- data/lib/graphql/schema/warden.rb +117 -31
- data/lib/graphql/schema/wrapper.rb +4 -1
- data/lib/graphql/schema.rb +1050 -302
- data/lib/graphql/static_validation/all_rules.rb +2 -1
- data/lib/graphql/static_validation/base_visitor.rb +48 -8
- data/lib/graphql/static_validation/definition_dependencies.rb +27 -7
- data/lib/graphql/static_validation/error.rb +3 -0
- data/lib/graphql/static_validation/interpreter_visitor.rb +1 -0
- data/lib/graphql/static_validation/literal_validator.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +4 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -0
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +3 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +3 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +9 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +295 -134
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +14 -2
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +1 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +3 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +3 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +1 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +4 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +1 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +3 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +1 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +3 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +4 -1
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +3 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +207 -51
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +3 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -3
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +1 -0
- data/lib/graphql/static_validation/validation_context.rb +3 -2
- data/lib/graphql/static_validation/validation_timeout_error.rb +1 -0
- data/lib/graphql/static_validation/validator.rb +41 -16
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +1 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +85 -65
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +1 -0
- data/lib/graphql/subscriptions/event.rb +25 -6
- data/lib/graphql/subscriptions/serialize.rb +58 -19
- data/lib/graphql/subscriptions.rb +172 -46
- data/lib/graphql/testing/helpers.rb +17 -4
- data/lib/graphql/testing/mock_action_cable.rb +55 -33
- data/lib/graphql/testing.rb +1 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +17 -9
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_trace.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -1
- data/lib/graphql/tracing/appsignal_trace.rb +16 -7
- data/lib/graphql/tracing/appsignal_tracing.rb +7 -3
- data/lib/graphql/tracing/call_legacy_tracers.rb +1 -0
- data/lib/graphql/tracing/data_dog_trace.rb +17 -6
- data/lib/graphql/tracing/data_dog_tracing.rb +10 -3
- data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace.rb +105 -42
- data/lib/graphql/tracing/legacy_hooks_trace.rb +5 -0
- data/lib/graphql/tracing/legacy_trace.rb +1 -0
- data/lib/graphql/tracing/monitor_trace.rb +17 -11
- data/lib/graphql/tracing/new_relic_trace.rb +17 -8
- data/lib/graphql/tracing/new_relic_tracing.rb +7 -3
- data/lib/graphql/tracing/notifications_trace.rb +11 -8
- data/lib/graphql/tracing/notifications_tracing.rb +23 -7
- data/lib/graphql/tracing/null_trace.rb +1 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +1 -0
- data/lib/graphql/tracing/perfetto_trace.rb +41 -19
- data/lib/graphql/tracing/platform_trace.rb +3 -1
- data/lib/graphql/tracing/platform_tracing.rb +16 -7
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +1 -0
- data/lib/graphql/tracing/prometheus_trace.rb +22 -13
- data/lib/graphql/tracing/prometheus_tracing.rb +1 -0
- data/lib/graphql/tracing/scout_trace.rb +10 -4
- data/lib/graphql/tracing/scout_tracing.rb +7 -3
- data/lib/graphql/tracing/sentry_trace.rb +12 -5
- data/lib/graphql/tracing/statsd_trace.rb +12 -6
- data/lib/graphql/tracing/statsd_tracing.rb +7 -1
- data/lib/graphql/tracing/trace.rb +231 -58
- data/lib/graphql/tracing.rb +25 -9
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/big_int.rb +1 -0
- data/lib/graphql/types/boolean.rb +1 -0
- data/lib/graphql/types/float.rb +1 -0
- data/lib/graphql/types/id.rb +1 -0
- data/lib/graphql/types/int.rb +2 -1
- data/lib/graphql/types/iso_8601_date.rb +21 -4
- data/lib/graphql/types/iso_8601_date_time.rb +33 -6
- data/lib/graphql/types/iso_8601_duration.rb +42 -9
- data/lib/graphql/types/json.rb +1 -0
- data/lib/graphql/types/relay/base_connection.rb +38 -32
- data/lib/graphql/types/relay/base_edge.rb +15 -9
- data/lib/graphql/types/relay/connection_behaviors.rb +19 -3
- data/lib/graphql/types/relay/edge_behaviors.rb +17 -4
- data/lib/graphql/types/relay/has_node_field.rb +6 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +6 -1
- data/lib/graphql/types/relay/node.rb +1 -0
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay/page_info.rb +1 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +1 -0
- data/lib/graphql/types/relay.rb +4 -3
- data/lib/graphql/types/string.rb +1 -0
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/unauthorized_enum_value_error.rb +4 -1
- data/lib/graphql/unauthorized_error.rb +11 -4
- data/lib/graphql/unauthorized_field_error.rb +4 -1
- data/lib/graphql/unresolved_type_error.rb +16 -5
- data/lib/graphql/version.rb +2 -1
- data/lib/graphql.rb +37 -9
- data/readme.md +1 -1
- metadata +89 -5
- data/.yardopts +0 -5
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
require "graphql/schema/build_from_definition/resolve_map"
|
|
3
4
|
|
|
4
5
|
module GraphQL
|
|
5
6
|
class Schema
|
|
6
7
|
module BuildFromDefinition
|
|
7
8
|
class << self
|
|
8
|
-
#
|
|
9
|
-
def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser,
|
|
9
|
+
# See [Schema.from_definition](rdoc-ref:Schema.from_definition)
|
|
10
|
+
def from_definition(schema_superclass, definition_string, default_resolve:, parser: GraphQL.default_parser, using: {}, base_types: {}, relay: false)
|
|
10
11
|
if defined?(parser::SchemaParser)
|
|
11
|
-
parser = parser
|
|
12
|
+
parser = parser.const_get(:SchemaParser)
|
|
12
13
|
end
|
|
13
|
-
from_document(schema_superclass, parser.parse(definition_string),
|
|
14
|
+
from_document(schema_superclass, parser.parse(definition_string), default_resolve: default_resolve, using: using, base_types: base_types, relay: relay)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser,
|
|
17
|
+
def from_definition_path(schema_superclass, definition_path, default_resolve:, parser: GraphQL.default_parser, using: {}, base_types: {}, relay: false)
|
|
17
18
|
if defined?(parser::SchemaParser)
|
|
18
|
-
parser = parser
|
|
19
|
+
parser = parser.const_get(:SchemaParser)
|
|
19
20
|
end
|
|
20
|
-
from_document(schema_superclass, parser.parse_file(definition_path),
|
|
21
|
+
from_document(schema_superclass, parser.parse_file(definition_path), default_resolve: default_resolve, using: using, base_types: base_types, relay: relay)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def from_document(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay: false)
|
|
@@ -25,8 +26,9 @@ module GraphQL
|
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
#--
|
|
30
|
+
# @requires_ancestor: Kernel
|
|
31
|
+
module Builder # :nodoc:
|
|
30
32
|
include GraphQL::EmptyObjects
|
|
31
33
|
extend self
|
|
32
34
|
|
|
@@ -46,21 +48,61 @@ module GraphQL
|
|
|
46
48
|
default_resolve = ResolveMap.new(default_resolve)
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
definitions = document.definitions #: Array[untyped]
|
|
52
|
+
schema_defns = definitions.select { |d| d.is_a?(GraphQL::Language::Nodes::SchemaDefinition) }
|
|
50
53
|
if schema_defns.size > 1
|
|
51
54
|
raise InvalidDocumentError.new('Must provide only one schema definition.')
|
|
52
55
|
end
|
|
53
|
-
schema_definition = schema_defns.first
|
|
56
|
+
schema_definition = schema_defns.first #: GraphQL::Language::Nodes::SchemaDefinition?
|
|
54
57
|
types = {}
|
|
55
58
|
directives = schema_superclass.directives.dup
|
|
56
|
-
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
# Directive applications are queued while types are built, then applied once every type is complete,
|
|
60
|
+
# because applying a directive coerces its arguments, which requires fully-built input types.
|
|
61
|
+
queued_directives = []
|
|
62
|
+
definitions_by_name = {}
|
|
63
|
+
# Classes (or modules, for interfaces) made before any type is built, so that references to them don't need late-bound types
|
|
64
|
+
type_classes = {}
|
|
65
|
+
interface_definitions = {}
|
|
66
|
+
definitions.each do |d|
|
|
67
|
+
if d.respond_to?(:name)
|
|
68
|
+
definitions_by_name[d.name] ||= d
|
|
69
|
+
if !type_classes.key?(d.name)
|
|
70
|
+
base_type = case d
|
|
71
|
+
when GraphQL::Language::Nodes::ObjectTypeDefinition then base_types[:object]
|
|
72
|
+
when GraphQL::Language::Nodes::EnumTypeDefinition then base_types[:enum]
|
|
73
|
+
when GraphQL::Language::Nodes::InputObjectTypeDefinition then base_types[:input_object]
|
|
74
|
+
when GraphQL::Language::Nodes::UnionTypeDefinition then base_types[:union]
|
|
75
|
+
when GraphQL::Language::Nodes::ScalarTypeDefinition then base_types[:scalar]
|
|
76
|
+
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
|
77
|
+
interface_definitions[d.name] = d
|
|
78
|
+
type_classes[d.name] = new_interface_module(d.name, base_types[:interface])
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
if base_type
|
|
82
|
+
type_classes[d.name] = Class.new(base_type) {
|
|
83
|
+
#: self as singleton(GraphQL::Schema::Member)
|
|
84
|
+
graphql_name(d.name)
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
type_resolver = TypeResolver.new(types, directives, queued_directives, type_classes) { |type_name|
|
|
91
|
+
types[type_name] ||= if (type_class = type_classes[type_name])
|
|
92
|
+
type_class
|
|
93
|
+
elsif !definitions_by_name.key?(type_name) && (built_in_type = GraphQL::Schema::BUILT_IN_TYPES[type_name])
|
|
94
|
+
built_in_type
|
|
95
|
+
else
|
|
96
|
+
Schema::LateBoundType.new(type_name)
|
|
97
|
+
end
|
|
98
|
+
}
|
|
99
|
+
# Make a different type resolver because directive argument types must be real classes (not late-bound)
|
|
100
|
+
# when queued directives are applied. It builds types eagerly. (Each type registers itself in `types`
|
|
101
|
+
# before building its members, so cycles between input objects terminate.)
|
|
60
102
|
directive_type_resolver = nil
|
|
61
|
-
directive_type_resolver =
|
|
103
|
+
directive_type_resolver = TypeResolver.new(types, directives, queued_directives, type_classes) { |type_name|
|
|
62
104
|
types[type_name] ||= begin
|
|
63
|
-
defn =
|
|
105
|
+
defn = definitions_by_name[type_name]
|
|
64
106
|
if defn
|
|
65
107
|
build_definition_from_node(defn, directive_type_resolver, default_resolve, base_types)
|
|
66
108
|
elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
|
|
@@ -69,10 +111,22 @@ module GraphQL
|
|
|
69
111
|
raise "No definition for #{type_name.inspect} found in schema document or built-in types. Add a definition for it or remove it."
|
|
70
112
|
end
|
|
71
113
|
end
|
|
72
|
-
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
build_interface = ->(interface_name, resolver) {
|
|
117
|
+
if (interface_definition = interface_definitions.delete(interface_name)) && type_classes[interface_name]
|
|
118
|
+
check_transitive_interfaces(interface_definition, definitions_by_name)
|
|
119
|
+
build_interface_type(interface_definition, resolver, base_types[:interface])
|
|
120
|
+
end
|
|
121
|
+
}
|
|
122
|
+
type_resolver.build_interface = build_interface
|
|
123
|
+
directive_type_resolver.build_interface = build_interface
|
|
124
|
+
type_links = TypeLinks.new
|
|
125
|
+
type_resolver.links = type_links
|
|
126
|
+
directive_type_resolver.links = type_links
|
|
73
127
|
|
|
74
128
|
directives.merge!(GraphQL::Schema.default_directives)
|
|
75
|
-
|
|
129
|
+
definitions.each do |definition|
|
|
76
130
|
if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
|
|
77
131
|
directives[definition.name] = build_directive(definition, directive_type_resolver)
|
|
78
132
|
end
|
|
@@ -81,9 +135,8 @@ module GraphQL
|
|
|
81
135
|
# In case any directives referenced built-in types for their arguments:
|
|
82
136
|
replace_late_bound_types_with_built_in(types)
|
|
83
137
|
|
|
84
|
-
schema_extensions = nil
|
|
85
|
-
|
|
86
|
-
document.definitions.each do |definition|
|
|
138
|
+
schema_extensions = nil #: Array[untyped]?
|
|
139
|
+
definitions.each do |definition|
|
|
87
140
|
case definition
|
|
88
141
|
when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
|
|
89
142
|
nil # already handled
|
|
@@ -99,25 +152,11 @@ module GraphQL
|
|
|
99
152
|
else
|
|
100
153
|
# It's possible that this was already loaded by the directives
|
|
101
154
|
prev_type = types[definition.name]
|
|
102
|
-
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
|
|
155
|
+
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType) || type_classes[definition.name]
|
|
103
156
|
if definition.is_a?(GraphQL::Language::Nodes::ObjectTypeDefinition) || definition.is_a?(Language::Nodes::InterfaceTypeDefinition)
|
|
104
|
-
|
|
105
|
-
if !interface_names.empty?
|
|
106
|
-
definitions_by_name ||= document.definitions.each_with_object({}) do |d, by_name|
|
|
107
|
-
by_name[d.name] ||= d if d.respond_to?(:name)
|
|
108
|
-
end
|
|
109
|
-
transitive_names = interface_names.map { |n| definitions_by_name[n]&.interfaces&.map(&:name) }
|
|
110
|
-
transitive_names.flatten!
|
|
111
|
-
transitive_names.compact!
|
|
112
|
-
else
|
|
113
|
-
transitive_names = interface_names
|
|
114
|
-
end
|
|
115
|
-
if !(missing_transitive_interfaces = transitive_names - interface_names).empty?
|
|
116
|
-
raise GraphQL::Schema::InvalidDocumentError, "type #{definition.name} is missing one or more transitive interface names: #{missing_transitive_interfaces.join(", ")}. Add them to the type's `implements` list and try again."
|
|
117
|
-
end
|
|
157
|
+
check_transitive_interfaces(definition, definitions_by_name)
|
|
118
158
|
end
|
|
119
|
-
|
|
120
|
-
types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve, base_types)
|
|
159
|
+
build_definition_from_node(definition, type_resolver, default_resolve, base_types)
|
|
121
160
|
end
|
|
122
161
|
end
|
|
123
162
|
end
|
|
@@ -185,15 +224,25 @@ module GraphQL
|
|
|
185
224
|
end
|
|
186
225
|
end
|
|
187
226
|
|
|
227
|
+
# All types are built now, so directive arguments can be coerced
|
|
228
|
+
apply_queued_directives(queued_directives)
|
|
229
|
+
|
|
188
230
|
builder = self
|
|
189
231
|
|
|
190
232
|
found_types = types.values
|
|
191
|
-
object_types = found_types.select { |t| t.
|
|
233
|
+
object_types = found_types.select { |t| t.is_a?(Class) && t < GraphQL::Schema::Object }
|
|
192
234
|
schema_class = Class.new(schema_superclass) do
|
|
235
|
+
#: self as singleton(GraphQL::Schema)
|
|
193
236
|
begin
|
|
194
237
|
# Add these first so that there's some chance of resolving late-bound types
|
|
195
|
-
|
|
196
|
-
|
|
238
|
+
if !builder.add_linked_types(self, found_types, type_links, directives, base_types)
|
|
239
|
+
add_type_and_traverse(found_types, root: false)
|
|
240
|
+
end
|
|
241
|
+
# Without visibility, this would only re-traverse types that were just added
|
|
242
|
+
# (and `own_orphan_types` is cleared below), so it can be skipped.
|
|
243
|
+
if use_visibility_profile? || visibility
|
|
244
|
+
orphan_types(object_types)
|
|
245
|
+
end
|
|
197
246
|
query query_root_type
|
|
198
247
|
mutation mutation_root_type
|
|
199
248
|
subscription subscription_root_type
|
|
@@ -228,6 +277,7 @@ module GraphQL
|
|
|
228
277
|
if schema_definition
|
|
229
278
|
ast_node(schema_definition)
|
|
230
279
|
builder.build_directives(self, schema_definition, type_resolver)
|
|
280
|
+
builder.apply_queued_directives(queued_directives)
|
|
231
281
|
end
|
|
232
282
|
|
|
233
283
|
using.each do |plugin, options|
|
|
@@ -245,7 +295,7 @@ module GraphQL
|
|
|
245
295
|
attr_accessor :definition_default_resolve
|
|
246
296
|
end
|
|
247
297
|
|
|
248
|
-
|
|
298
|
+
@definition_default_resolve = default_resolve
|
|
249
299
|
|
|
250
300
|
def definition_default_resolve
|
|
251
301
|
self.class.definition_default_resolve
|
|
@@ -262,10 +312,133 @@ module GraphQL
|
|
|
262
312
|
build_directives(schema_class, ext, type_resolver)
|
|
263
313
|
end
|
|
264
314
|
end
|
|
315
|
+
apply_queued_directives(queued_directives)
|
|
316
|
+
|
|
317
|
+
directives.each_value do |dir_class|
|
|
318
|
+
if dir_class.respond_to?(:coerced_arguments_cache=) && dir_class.coerced_arguments_cache
|
|
319
|
+
dir_class.coerced_arguments_cache = nil
|
|
320
|
+
end
|
|
321
|
+
end
|
|
265
322
|
|
|
266
323
|
schema_class
|
|
267
324
|
end
|
|
268
325
|
|
|
326
|
+
# References between types in this document, recorded while they're built.
|
|
327
|
+
class TypeLinks
|
|
328
|
+
def initialize
|
|
329
|
+
@references = {}.compare_by_identity
|
|
330
|
+
@arguments = []
|
|
331
|
+
@complete = true
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Hash of type => Array of the fields and arguments that use it (no duplicates, since each one is added once)
|
|
335
|
+
attr_reader :references
|
|
336
|
+
|
|
337
|
+
attr_reader :arguments
|
|
338
|
+
|
|
339
|
+
# True if everything was recorded, so the generic traversal isn't needed
|
|
340
|
+
def complete?
|
|
341
|
+
@complete
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def incomplete!
|
|
345
|
+
@complete = false
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def add_argument(argument, argument_type)
|
|
349
|
+
@arguments << argument
|
|
350
|
+
add_reference(argument, argument_type)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def add_reference(member, member_type)
|
|
354
|
+
member_type = member_type.unwrap
|
|
355
|
+
if member_type.is_a?(Schema::LateBoundType)
|
|
356
|
+
# The generic traversal will raise an error for this
|
|
357
|
+
incomplete!
|
|
358
|
+
else
|
|
359
|
+
(@references[member_type] ||= []) << member
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# Like `schema_class.add_type_and_traverse(found_types, root: false)`, but it uses the links recorded while types were built
|
|
365
|
+
# instead of a traversal. (Directive classes are added later, with `directives(...)`.)
|
|
366
|
+
# Returns false if the traversal is required, for example, when base types have their own fields or interfaces.
|
|
367
|
+
def add_linked_types(schema_class, found_types, type_links, directives, base_types)
|
|
368
|
+
if !type_links.complete? ||
|
|
369
|
+
schema_class.use_visibility_profile? ||
|
|
370
|
+
# A redefined `@deprecated` isn't the one used by `deprecation_reason:`, so the traversal would find another directive.
|
|
371
|
+
!directives["deprecated"].equal?(GraphQL::Schema::Directive::Deprecated) ||
|
|
372
|
+
!base_types_without_members?(base_types)
|
|
373
|
+
return false
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
own_types = schema_class.send(:own_types)
|
|
377
|
+
found_types.each do |type|
|
|
378
|
+
if !(Module === type)
|
|
379
|
+
return false
|
|
380
|
+
end
|
|
381
|
+
type = type #: as GraphQL::Schema::Member::type_definition
|
|
382
|
+
if (Class === type && GraphQL::Schema::Directive > type) ||
|
|
383
|
+
((prev_type = own_types[type.graphql_name]) && !prev_type.equal?(type))
|
|
384
|
+
return false
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# Like the traversal, check each argument's type now (it raises an error if the type is invalid)
|
|
389
|
+
type_links.arguments.each(&:type)
|
|
390
|
+
|
|
391
|
+
possible_types = {}.compare_by_identity
|
|
392
|
+
possible_types_sets = {}.compare_by_identity
|
|
393
|
+
union_memberships = {}
|
|
394
|
+
found_types.each do |type|
|
|
395
|
+
own_types[type.graphql_name] = type
|
|
396
|
+
if Class === type
|
|
397
|
+
if GraphQL::Schema::Object > type
|
|
398
|
+
(possible_types[type] ||= []) << type
|
|
399
|
+
object_type = type #: as singleton(GraphQL::Schema::Object)
|
|
400
|
+
object_type.interface_type_memberships.each do |type_membership|
|
|
401
|
+
interface_type = type_membership.abstract_type
|
|
402
|
+
if (possible_types_sets[interface_type] ||= Set.new).add?(type)
|
|
403
|
+
(possible_types[interface_type] ||= []) << type
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
elsif GraphQL::Schema::Union > type
|
|
407
|
+
union_type = type #: as singleton(GraphQL::Schema::Union)
|
|
408
|
+
member_types = possible_types[type] = union_type.all_possible_types
|
|
409
|
+
member_types.each do |member_type|
|
|
410
|
+
(union_memberships[member_type.graphql_name] ||= []) << type
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
schema_class.send(:own_possible_types).merge!(possible_types) { |key, old_val, new_val| old_val + new_val }
|
|
417
|
+
schema_class.send(:own_union_memberships).merge!(union_memberships)
|
|
418
|
+
own_references_to = schema_class.send(:own_references_to)
|
|
419
|
+
type_links.references.each do |thing, new_refs|
|
|
420
|
+
prev_refs = own_references_to[thing]
|
|
421
|
+
own_references_to[thing] = prev_refs ? (prev_refs + (new_refs - prev_refs)) : new_refs
|
|
422
|
+
end
|
|
423
|
+
type_links.arguments.each do |argument|
|
|
424
|
+
if argument.default_value?
|
|
425
|
+
argument.validate_default_value
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
true
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
def base_types_without_members?(base_types)
|
|
432
|
+
object = base_types[:object]
|
|
433
|
+
interface = base_types[:interface]
|
|
434
|
+
object.all_field_definitions.empty? && object.interface_type_memberships.empty? && object.directives.empty? &&
|
|
435
|
+
interface.all_field_definitions.empty? && interface.interface_type_memberships.empty? && interface.directives.empty? && interface.orphan_types.empty? &&
|
|
436
|
+
base_types[:input_object].all_argument_definitions.empty? && base_types[:input_object].directives.empty? &&
|
|
437
|
+
base_types[:union].all_possible_types.empty? && base_types[:union].directives.empty? &&
|
|
438
|
+
base_types[:enum].all_enum_value_definitions.empty? && base_types[:enum].directives.empty? &&
|
|
439
|
+
base_types[:scalar].directives.empty?
|
|
440
|
+
end
|
|
441
|
+
|
|
269
442
|
NullResolveType = ->(type, obj, ctx) {
|
|
270
443
|
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
|
|
271
444
|
}
|
|
@@ -293,7 +466,13 @@ module GraphQL
|
|
|
293
466
|
# with their actual definitions.
|
|
294
467
|
#
|
|
295
468
|
# (Schema definitions are allowed to reference those built-ins without redefining them.)
|
|
296
|
-
#
|
|
469
|
+
#
|
|
470
|
+
# **Returns**
|
|
471
|
+
#
|
|
472
|
+
# - `Object` — void
|
|
473
|
+
#
|
|
474
|
+
# :call-seq:
|
|
475
|
+
# replace_late_bound_types_with_built_in(types) -> Object
|
|
297
476
|
def replace_late_bound_types_with_built_in(types)
|
|
298
477
|
GraphQL::Schema::BUILT_IN_TYPES.each do |scalar_name, built_in_scalar|
|
|
299
478
|
existing_type = types[scalar_name]
|
|
@@ -303,46 +482,54 @@ module GraphQL
|
|
|
303
482
|
end
|
|
304
483
|
end
|
|
305
484
|
|
|
485
|
+
# Apply `ast_node`'s directives to `definition`. If any of those directives has arguments,
|
|
486
|
+
# they're queued for {apply_queued_directives} because coercing arguments requires fully-built types.
|
|
487
|
+
# Directives without arguments are applied right away, since some (like `@oneOf`) affect how the rest of the type is built.
|
|
306
488
|
def build_directives(definition, ast_node, type_resolver)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
definition.directive(dir_class, **options)
|
|
314
|
-
end
|
|
489
|
+
return if ast_node.directives.empty?
|
|
490
|
+
|
|
491
|
+
if ast_node.directives.all? { |dir_node| dir_node.name == "deprecated" || type_resolver.directive_without_arguments?(dir_node.name) }
|
|
492
|
+
apply_directives(definition, ast_node, type_resolver)
|
|
493
|
+
else
|
|
494
|
+
type_resolver.queued_directives << [definition, ast_node, type_resolver]
|
|
315
495
|
end
|
|
316
496
|
end
|
|
317
497
|
|
|
318
|
-
def
|
|
319
|
-
|
|
498
|
+
def apply_queued_directives(queued_directives)
|
|
499
|
+
until queued_directives.empty?
|
|
500
|
+
apply_directives(*queued_directives.shift)
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def apply_directives(definition, ast_node, type_resolver)
|
|
505
|
+
is_schema = Class === definition && GraphQL::Schema >= definition
|
|
320
506
|
ast_node.directives.each do |dir_node|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
507
|
+
# This is handled using `deprecation_reason`
|
|
508
|
+
next if dir_node.name == "deprecated"
|
|
509
|
+
dir_class = type_resolver.call(dir_node.name)
|
|
510
|
+
if dir_class.nil?
|
|
511
|
+
raise ArgumentError, "No definition for @#{dir_node.name} #{ast_node.respond_to?(:name) ? "on #{ast_node.name} " : ""}at #{ast_node.line}:#{ast_node.col}"
|
|
512
|
+
end
|
|
513
|
+
options = args_to_kwargs(dir_class, dir_node, type_resolver)
|
|
514
|
+
if is_schema
|
|
515
|
+
schema_class = definition #: as singleton(GraphQL::Schema)
|
|
516
|
+
schema_class.schema_directive(dir_class, **options)
|
|
324
517
|
else
|
|
325
|
-
dir_class
|
|
326
|
-
if dir_class.nil?
|
|
327
|
-
raise ArgumentError, "No definition for @#{dir_node.name} #{ast_node.respond_to?(:name) ? "on #{ast_node.name} " : ""}at #{ast_node.line}:#{ast_node.col}"
|
|
328
|
-
end
|
|
329
|
-
options = args_to_kwargs(dir_class, dir_node)
|
|
330
|
-
dirs << [dir_class, options]
|
|
518
|
+
definition.directive(dir_class, **options)
|
|
331
519
|
end
|
|
332
520
|
end
|
|
333
|
-
dirs
|
|
334
521
|
end
|
|
335
522
|
|
|
336
|
-
def args_to_kwargs(arg_owner, node)
|
|
523
|
+
def args_to_kwargs(arg_owner, node, type_resolver)
|
|
337
524
|
if node.respond_to?(:arguments)
|
|
338
525
|
kwargs = {}
|
|
339
526
|
node.arguments.each do |arg_node|
|
|
340
|
-
arg_defn =
|
|
341
|
-
kwargs[arg_defn.keyword] = args_to_kwargs(arg_defn.type.unwrap, arg_node.value)
|
|
527
|
+
arg_defn = type_resolver.get_argument(arg_owner, arg_node.name)
|
|
528
|
+
kwargs[arg_defn.keyword] = args_to_kwargs(arg_defn.type.unwrap, arg_node.value, type_resolver)
|
|
342
529
|
end
|
|
343
530
|
kwargs
|
|
344
531
|
elsif node.is_a?(Array)
|
|
345
|
-
node.map { |n| args_to_kwargs(arg_owner, n) }
|
|
532
|
+
node.map { |n| args_to_kwargs(arg_owner, n, type_resolver) }
|
|
346
533
|
elsif node.is_a?(Language::Nodes::Enum)
|
|
347
534
|
node.name
|
|
348
535
|
else
|
|
@@ -352,53 +539,56 @@ module GraphQL
|
|
|
352
539
|
end
|
|
353
540
|
|
|
354
541
|
def build_enum_type(enum_type_definition, type_resolver, base_type)
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
end
|
|
542
|
+
type_class = type_resolver.type_class(enum_type_definition.name, base_type) #: singleton(GraphQL::Schema::Enum)
|
|
543
|
+
type_resolver.register(type_class)
|
|
544
|
+
build_directives(type_class, enum_type_definition, type_resolver)
|
|
545
|
+
type_class.description(enum_type_definition.description)
|
|
546
|
+
type_class.ast_node(enum_type_definition)
|
|
547
|
+
build_values(type_class, enum_type_definition.values, type_resolver)
|
|
548
|
+
type_class
|
|
363
549
|
end
|
|
364
550
|
|
|
365
551
|
def build_values(type_class, enum_value_definitions, type_resolver)
|
|
366
552
|
enum_value_definitions.each do |enum_value_definition|
|
|
367
|
-
type_class.value(enum_value_definition.name,
|
|
553
|
+
enum_value = type_class.value(enum_value_definition.name,
|
|
368
554
|
value: enum_value_definition.name,
|
|
369
555
|
deprecation_reason: build_deprecation_reason(enum_value_definition.directives),
|
|
370
556
|
description: enum_value_definition.description,
|
|
371
|
-
directives: prepare_directives(enum_value_definition, type_resolver),
|
|
372
557
|
ast_node: enum_value_definition,
|
|
373
558
|
)
|
|
559
|
+
build_directives(enum_value, enum_value_definition, type_resolver)
|
|
374
560
|
end
|
|
375
561
|
end
|
|
376
562
|
|
|
377
563
|
def build_deprecation_reason(directives)
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
564
|
+
return if directives.empty?
|
|
565
|
+
directives.each do |d|
|
|
566
|
+
if d.name == "deprecated"
|
|
567
|
+
d.arguments.each do |a|
|
|
568
|
+
if a.name == "reason"
|
|
569
|
+
return a.value
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
return GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
nil
|
|
385
576
|
end
|
|
386
577
|
|
|
387
578
|
def build_scalar_type(scalar_type_definition, type_resolver, base_type, default_resolve:)
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
|
|
400
|
-
end
|
|
579
|
+
type_class = type_resolver.type_class(scalar_type_definition.name, base_type) #: singleton(GraphQL::Schema::Scalar)
|
|
580
|
+
type_resolver.register(type_class)
|
|
581
|
+
type_class.description(scalar_type_definition.description)
|
|
582
|
+
type_class.ast_node(scalar_type_definition)
|
|
583
|
+
build_directives(type_class, scalar_type_definition, type_resolver)
|
|
584
|
+
|
|
585
|
+
if default_resolve.respond_to?(:coerce_input)
|
|
586
|
+
# Put these method definitions in another method to avoid retaining `type_resolve`
|
|
587
|
+
# from this method's bindiing
|
|
588
|
+
build_scalar_type_coerce_method(type_class, :coerce_input, default_resolve)
|
|
589
|
+
build_scalar_type_coerce_method(type_class, :coerce_result, default_resolve)
|
|
401
590
|
end
|
|
591
|
+
type_class
|
|
402
592
|
end
|
|
403
593
|
|
|
404
594
|
def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
|
|
@@ -408,44 +598,68 @@ module GraphQL
|
|
|
408
598
|
end
|
|
409
599
|
|
|
410
600
|
def build_union_type(union_type_definition, type_resolver, base_type)
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
end
|
|
601
|
+
type_class = type_resolver.type_class(union_type_definition.name, base_type) #: singleton(GraphQL::Schema::Union)
|
|
602
|
+
type_resolver.register(type_class)
|
|
603
|
+
type_class.description(union_type_definition.description)
|
|
604
|
+
type_class.possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
|
|
605
|
+
type_class.ast_node(union_type_definition)
|
|
606
|
+
build_directives(type_class, union_type_definition, type_resolver)
|
|
607
|
+
type_class
|
|
419
608
|
end
|
|
420
609
|
|
|
421
610
|
def build_object_type(object_type_definition, type_resolver, base_type)
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
|
431
|
-
end
|
|
611
|
+
type_class = type_resolver.type_class(object_type_definition.name, base_type) #: singleton(GraphQL::Schema::Object)
|
|
612
|
+
type_resolver.register(type_class)
|
|
613
|
+
type_class.description(object_type_definition.description)
|
|
614
|
+
type_class.ast_node(object_type_definition)
|
|
615
|
+
build_directives(type_class, object_type_definition, type_resolver)
|
|
616
|
+
build_interfaces(type_class, object_type_definition.interfaces, type_resolver)
|
|
617
|
+
build_fields(type_class, object_type_definition.fields, type_resolver, default_resolve: true)
|
|
618
|
+
type_class
|
|
432
619
|
end
|
|
433
620
|
|
|
434
621
|
def build_interfaces(type_class, interface_names, type_resolver)
|
|
435
622
|
interface_names.each do |interface_name|
|
|
623
|
+
# Implementing an interface copies some of its configuration, so it must be built first
|
|
624
|
+
type_resolver.build_interface_now(interface_name.name)
|
|
436
625
|
type_class.implements(type_resolver.call(interface_name))
|
|
437
626
|
end
|
|
438
627
|
end
|
|
439
628
|
|
|
440
|
-
def
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
629
|
+
def check_transitive_interfaces(definition, definitions_by_name)
|
|
630
|
+
interface_names = definition.interfaces.map(&:name)
|
|
631
|
+
if !interface_names.empty?
|
|
632
|
+
transitive_names = interface_names.map { |n|
|
|
633
|
+
defn = definitions_by_name[n]
|
|
634
|
+
# Other kinds of types don't have `interfaces`; `implements` raises a better error for them later.
|
|
635
|
+
defn.is_a?(Language::Nodes::InterfaceTypeDefinition) ? defn.interfaces.map(&:name) : nil
|
|
636
|
+
}
|
|
637
|
+
transitive_names.flatten!
|
|
638
|
+
transitive_names.compact!
|
|
639
|
+
else
|
|
640
|
+
transitive_names = interface_names
|
|
448
641
|
end
|
|
642
|
+
if !(missing_transitive_interfaces = transitive_names - interface_names).empty?
|
|
643
|
+
raise GraphQL::Schema::InvalidDocumentError, "type #{definition.name} is missing one or more transitive interface names: #{missing_transitive_interfaces.join(", ")}. Add them to the type's `implements` list and try again."
|
|
644
|
+
end
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
def new_interface_module(name, base_type)
|
|
648
|
+
Module.new {
|
|
649
|
+
#: self as GraphQL::Schema::Member::interface_definition
|
|
650
|
+
include base_type
|
|
651
|
+
graphql_name(name)
|
|
652
|
+
}
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
def build_input_object_type(input_object_type_definition, type_resolver, base_type)
|
|
656
|
+
type_class = type_resolver.type_class(input_object_type_definition.name, base_type) #: singleton(GraphQL::Schema::InputObject)
|
|
657
|
+
type_resolver.register(type_class)
|
|
658
|
+
type_class.description(input_object_type_definition.description)
|
|
659
|
+
type_class.ast_node(input_object_type_definition)
|
|
660
|
+
build_directives(type_class, input_object_type_definition, type_resolver)
|
|
661
|
+
build_arguments(type_class, input_object_type_definition.fields, type_resolver)
|
|
662
|
+
type_class
|
|
449
663
|
end
|
|
450
664
|
|
|
451
665
|
def build_default_value(default_value)
|
|
@@ -465,7 +679,8 @@ module GraphQL
|
|
|
465
679
|
|
|
466
680
|
def build_arguments(type_class, arguments, type_resolver)
|
|
467
681
|
builder = self
|
|
468
|
-
|
|
682
|
+
# Directive arguments are linked when directives are added to the schema
|
|
683
|
+
links = (Class === type_class && GraphQL::Schema::Directive > type_class) ? nil : type_resolver.links
|
|
469
684
|
arguments.each do |argument_defn|
|
|
470
685
|
default_value_kwargs = if !argument_defn.default_value.nil?
|
|
471
686
|
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
|
@@ -473,17 +688,19 @@ module GraphQL
|
|
|
473
688
|
EMPTY_HASH
|
|
474
689
|
end
|
|
475
690
|
|
|
476
|
-
|
|
691
|
+
argument_type = type_resolver.call(argument_defn.type)
|
|
692
|
+
argument = type_class.argument(
|
|
477
693
|
argument_defn.name,
|
|
478
|
-
type:
|
|
694
|
+
type: argument_type,
|
|
479
695
|
required: false,
|
|
480
696
|
description: argument_defn.description,
|
|
481
697
|
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
|
482
698
|
ast_node: argument_defn,
|
|
483
699
|
camelize: false,
|
|
484
|
-
directives: prepare_directives(argument_defn, type_resolver),
|
|
485
700
|
**default_value_kwargs
|
|
486
701
|
)
|
|
702
|
+
links&.add_argument(argument, argument_type)
|
|
703
|
+
builder.build_directives(argument, argument_defn, type_resolver)
|
|
487
704
|
end
|
|
488
705
|
end
|
|
489
706
|
|
|
@@ -496,87 +713,199 @@ module GraphQL
|
|
|
496
713
|
locations(*directive_definition.locations.map { |location| location.name.to_sym })
|
|
497
714
|
ast_node(directive_definition)
|
|
498
715
|
builder.build_arguments(self, directive_definition.arguments, type_resolver)
|
|
716
|
+
self.coerced_arguments_cache = {}
|
|
499
717
|
end
|
|
500
718
|
end
|
|
501
719
|
|
|
502
720
|
def build_interface_type(interface_type_definition, type_resolver, base_type)
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
builder.build_fields(self, interface_type_definition.fields, type_resolver, default_resolve: nil)
|
|
513
|
-
end
|
|
721
|
+
type_module = type_resolver.interface_module(interface_type_definition.name, base_type) #: GraphQL::Schema::Member::interface_definition
|
|
722
|
+
type_resolver.register(type_module)
|
|
723
|
+
type_module.description(interface_type_definition.description)
|
|
724
|
+
build_interfaces(type_module, interface_type_definition.interfaces, type_resolver)
|
|
725
|
+
type_module.ast_node(interface_type_definition)
|
|
726
|
+
build_directives(type_module, interface_type_definition, type_resolver)
|
|
727
|
+
build_fields(type_module, interface_type_definition.fields, type_resolver, default_resolve: nil)
|
|
728
|
+
type_module
|
|
514
729
|
end
|
|
515
730
|
|
|
516
731
|
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
|
|
517
732
|
builder = self
|
|
518
|
-
|
|
733
|
+
# If `owner.field` isn't customized, make fields directly. It's the same, but faster.
|
|
734
|
+
field_class = owner.method(:field).owner.equal?(GraphQL::Schema::Member::HasFields) ? owner.field_class : nil
|
|
735
|
+
resolve_method_names = type_resolver.field_resolve_methods.method_names
|
|
736
|
+
links = type_resolver.links
|
|
737
|
+
# Custom field classes might add arguments (for example, with extensions), which the links wouldn't include
|
|
738
|
+
if !field_class.equal?(GraphQL::Schema::Field)
|
|
739
|
+
links.incomplete!
|
|
740
|
+
end
|
|
519
741
|
field_definitions.each do |field_definition|
|
|
520
|
-
resolve_method_name =
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
742
|
+
resolve_method_name = resolve_method_names[field_definition.name]
|
|
743
|
+
if field_class
|
|
744
|
+
schema_field_defn = field_class.new(
|
|
745
|
+
name: field_definition.name,
|
|
746
|
+
owner: owner,
|
|
747
|
+
description: field_definition.description,
|
|
748
|
+
type: (field_type = type_resolver.call(field_definition.type)),
|
|
749
|
+
null: true,
|
|
750
|
+
connection_extension: nil,
|
|
751
|
+
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
|
752
|
+
ast_node: field_definition,
|
|
753
|
+
method_conflict_warning: false,
|
|
754
|
+
camelize: false,
|
|
755
|
+
resolver_method: resolve_method_name,
|
|
756
|
+
resolve_batch: resolve_method_name,
|
|
757
|
+
)
|
|
758
|
+
owner.add_field(schema_field_defn)
|
|
759
|
+
else
|
|
760
|
+
schema_field_defn = owner.field(
|
|
761
|
+
field_definition.name,
|
|
762
|
+
description: field_definition.description,
|
|
763
|
+
type: (field_type = type_resolver.call(field_definition.type)),
|
|
764
|
+
null: true,
|
|
765
|
+
connection_extension: nil,
|
|
766
|
+
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
|
767
|
+
ast_node: field_definition,
|
|
768
|
+
method_conflict_warning: false,
|
|
769
|
+
camelize: false,
|
|
770
|
+
resolver_method: resolve_method_name,
|
|
771
|
+
resolve_batch: resolve_method_name,
|
|
772
|
+
)
|
|
773
|
+
end
|
|
535
774
|
|
|
775
|
+
links.add_reference(schema_field_defn, field_type)
|
|
776
|
+
builder.build_directives(schema_field_defn, field_definition, type_resolver)
|
|
536
777
|
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
|
537
778
|
|
|
538
779
|
# Don't do this for interfaces
|
|
539
780
|
if default_resolve
|
|
540
|
-
define_field_resolve_method(owner, resolve_method_name, field_definition.name)
|
|
781
|
+
define_field_resolve_method(owner, resolve_method_name, field_definition.name, type_resolver)
|
|
541
782
|
end
|
|
542
783
|
end
|
|
543
784
|
end
|
|
544
785
|
|
|
545
|
-
def define_field_resolve_method(owner, method_name, field_name)
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
786
|
+
def define_field_resolve_method(owner, method_name, field_name, type_resolver)
|
|
787
|
+
resolve_methods = type_resolver.field_resolve_methods
|
|
788
|
+
resolve_methods.field_names[method_name.to_sym] = field_name
|
|
789
|
+
owner.define_method(method_name, &resolve_methods.instance_method_proc)
|
|
790
|
+
owner.define_singleton_method(method_name, &resolve_methods.singleton_method_proc)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
# Every field's resolve methods share these procs. They use the method's name to find the field.
|
|
794
|
+
class FieldResolveMethods
|
|
795
|
+
def initialize
|
|
796
|
+
@method_names = Hash.new { |h, field_name| h[field_name] = -"resolve_field_#{field_name}" }
|
|
797
|
+
field_names = @field_names = {}
|
|
798
|
+
@instance_method_proc = proc { |**args|
|
|
799
|
+
#: self as GraphQL::Schema::Object
|
|
800
|
+
owner = self.class
|
|
801
|
+
field_instance = context.types.field(owner, field_names[__method__])
|
|
802
|
+
context.schema.definition_default_resolve.call(owner, field_instance, object, args, context)
|
|
803
|
+
}
|
|
804
|
+
@singleton_method_proc = proc { |objects, context, **args|
|
|
805
|
+
field_instance = context.types.field(self, field_names[__method__])
|
|
806
|
+
objects.map do |object|
|
|
807
|
+
context.schema.definition_default_resolve.call(self, field_instance, object, args, context)
|
|
808
|
+
end
|
|
809
|
+
}
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
# Field names by resolve method name
|
|
813
|
+
attr_reader :field_names
|
|
814
|
+
|
|
815
|
+
# Resolve method names by field name
|
|
816
|
+
attr_reader :method_names
|
|
817
|
+
|
|
818
|
+
attr_reader :instance_method_proc, :singleton_method_proc
|
|
556
819
|
end
|
|
557
820
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
821
|
+
class TypeResolver
|
|
822
|
+
def initialize(lookup_hash, directives, queued_directives, type_classes, &missing_type_handler)
|
|
823
|
+
@lookup_hash = lookup_hash
|
|
824
|
+
@directives = directives
|
|
825
|
+
@queued_directives = queued_directives
|
|
826
|
+
@type_classes = type_classes
|
|
827
|
+
@missing_type_handler = missing_type_handler
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
# The class made ahead of time for `type_name` (returned once, to be built), or a new subclass of `base_type`
|
|
831
|
+
def type_class(type_name, base_type)
|
|
832
|
+
@type_classes.delete(type_name) || Class.new(base_type) {
|
|
833
|
+
#: self as singleton(GraphQL::Schema::Member)
|
|
834
|
+
graphql_name(type_name)
|
|
835
|
+
}
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
def interface_module(type_name, base_type)
|
|
839
|
+
@type_classes.delete(type_name) || Builder.new_interface_module(type_name, base_type)
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
attr_writer :build_interface
|
|
843
|
+
|
|
844
|
+
attr_accessor :links
|
|
845
|
+
|
|
846
|
+
def build_interface_now(interface_name)
|
|
847
|
+
@build_interface&.call(interface_name, self)
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
# Directive applications waiting for {Builder#apply_queued_directives}
|
|
851
|
+
attr_reader :queued_directives
|
|
852
|
+
|
|
853
|
+
# Like `owner.get_argument(argument_name)`, but cached. Directives are applied after types are built,
|
|
854
|
+
# so their arguments don't change while this cache is used.
|
|
855
|
+
def get_argument(owner, argument_name)
|
|
856
|
+
@arguments_by_owner ||= {}.compare_by_identity
|
|
857
|
+
owner_arguments = @arguments_by_owner[owner] ||= {}
|
|
858
|
+
if owner_arguments.key?(argument_name)
|
|
859
|
+
owner_arguments[argument_name]
|
|
860
|
+
else
|
|
861
|
+
owner_arguments[argument_name] = owner.get_argument(argument_name)
|
|
862
|
+
end
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
def field_resolve_methods
|
|
866
|
+
@field_resolve_methods ||= FieldResolveMethods.new
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
# Add `type` to the lookup hash. Types call this before building their members, so that references back to them (including cycles) find this type.
|
|
870
|
+
def register(type)
|
|
871
|
+
@lookup_hash[type.graphql_name] = type
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
# The already-defined directive class named `name`, or `nil` if there isn't one yet
|
|
875
|
+
def directive_class(name)
|
|
876
|
+
@directives[name]
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
def directive_without_arguments?(name)
|
|
880
|
+
@directives_without_arguments ||= {}
|
|
881
|
+
if @directives_without_arguments.key?(name)
|
|
882
|
+
@directives_without_arguments[name]
|
|
883
|
+
else
|
|
884
|
+
dir_class = @directives[name]
|
|
885
|
+
# Don't cache unknown directives, they might be defined later
|
|
886
|
+
dir_class ? (@directives_without_arguments[name] = dir_class.all_argument_definitions.empty?) : false
|
|
887
|
+
end
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
def call(ast_node)
|
|
561
891
|
case ast_node
|
|
562
892
|
when GraphQL::Language::Nodes::TypeName
|
|
563
893
|
type_name = ast_node.name
|
|
564
|
-
if lookup_hash.key?(type_name)
|
|
565
|
-
lookup_hash[type_name]
|
|
894
|
+
if @lookup_hash.key?(type_name)
|
|
895
|
+
@lookup_hash[type_name]
|
|
566
896
|
else
|
|
567
|
-
missing_type_handler.call(type_name)
|
|
897
|
+
@missing_type_handler.call(type_name)
|
|
568
898
|
end
|
|
569
899
|
when GraphQL::Language::Nodes::NonNullType
|
|
570
|
-
|
|
900
|
+
call(ast_node.of_type).to_non_null_type
|
|
571
901
|
when GraphQL::Language::Nodes::ListType
|
|
572
|
-
|
|
902
|
+
call(ast_node.of_type).to_list_type
|
|
573
903
|
when String
|
|
574
|
-
directives[ast_node] ||= missing_type_handler.call(ast_node)
|
|
904
|
+
@directives[ast_node] ||= @missing_type_handler.call(ast_node)
|
|
575
905
|
else
|
|
576
906
|
raise "Unexpected ast_node: #{ast_node.inspect}"
|
|
577
907
|
end
|
|
578
|
-
|
|
579
|
-
resolve_type_proc
|
|
908
|
+
end
|
|
580
909
|
end
|
|
581
910
|
end
|
|
582
911
|
|