graphql 1.10.2 → 2.0.21
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 +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +45 -8
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +49 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- 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_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 +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +24 -33
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +30 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +125 -117
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +52 -36
- data/lib/graphql/analysis/ast.rb +7 -8
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +31 -18
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +26 -18
- data/lib/graphql/dataloader/null_dataloader.rb +24 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +164 -0
- data/lib/graphql/dataloader.rb +311 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +77 -44
- 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 +104 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +62 -24
- data/lib/graphql/execution/interpreter/runtime.rb +826 -464
- data/lib/graphql/execution/interpreter.rb +206 -68
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +55 -136
- data/lib/graphql/execution/multiplex.rb +6 -162
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +7 -2
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +11 -5
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +4 -17
- 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 +11 -6
- data/lib/graphql/introspection/type_type.rb +31 -14
- data/lib/graphql/introspection.rb +100 -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 +96 -44
- data/lib/graphql/language/lexer.rb +216 -1462
- data/lib/graphql/language/nodes.rb +126 -129
- data/lib/graphql/language/parser.rb +997 -933
- data/lib/graphql/language/parser.y +148 -118
- data/lib/graphql/language/printer.rb +48 -23
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +192 -84
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +45 -3
- data/lib/graphql/pagination/array_connection.rb +6 -4
- data/lib/graphql/pagination/connection.rb +105 -23
- data/lib/graphql/pagination/connections.rb +62 -35
- data/lib/graphql/pagination/relation_connection.rb +88 -36
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +203 -198
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +33 -7
- data/lib/graphql/query/null_context.rb +22 -9
- data/lib/graphql/query/validation_pipeline.rb +16 -38
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +36 -12
- data/lib/graphql/query.rb +92 -44
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +41 -10
- data/lib/graphql/relay/range_add.rb +17 -10
- data/lib/graphql/relay.rb +0 -15
- 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/schema/addition.rb +245 -0
- data/lib/graphql/schema/argument.rb +250 -46
- 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 +243 -89
- 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/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +108 -20
- data/lib/graphql/schema/enum.rb +105 -44
- data/lib/graphql/schema/enum_value.rb +15 -25
- data/lib/graphql/schema/field/connection_extension.rb +50 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +476 -331
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +6 -8
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +133 -121
- data/lib/graphql/schema/interface.rb +17 -45
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +25 -8
- data/lib/graphql/schema/loader.rb +139 -103
- data/lib/graphql/schema/member/base_dsl_methods.rb +29 -35
- data/lib/graphql/schema/member/build_type.rb +19 -14
- data/lib/graphql/schema/member/has_arguments.rb +310 -26
- data/lib/graphql/schema/member/has_ast_node.rb +16 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
- data/lib/graphql/schema/member/has_directives.rb +118 -0
- data/lib/graphql/schema/member/has_fields.rb +164 -42
- data/lib/graphql/schema/member/has_interfaces.rb +129 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +57 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +12 -7
- data/lib/graphql/schema/object.rb +35 -69
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
- data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
- data/lib/graphql/schema/resolver.rb +144 -79
- data/lib/graphql/schema/scalar.rb +27 -18
- data/lib/graphql/schema/subscription.rb +55 -26
- data/lib/graphql/schema/timeout.rb +45 -35
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +21 -4
- data/lib/graphql/schema/union.rb +48 -13
- data/lib/graphql/schema/unique_within_type.rb +1 -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 +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +185 -32
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +471 -1116
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +13 -27
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +69 -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 +12 -6
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +92 -49
- 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/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -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 +14 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +32 -20
- data/lib/graphql/static_validation.rb +1 -2
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +126 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +81 -35
- data/lib/graphql/subscriptions/instrumentation.rb +0 -52
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +113 -58
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +26 -2
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +64 -43
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +23 -71
- data/lib/graphql/type_kinds.rb +6 -3
- 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 +20 -9
- data/lib/graphql/types/iso_8601_date_time.rb +36 -10
- data/lib/graphql/types/relay/base_connection.rb +18 -92
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +75 -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 +25 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
- data/lib/graphql/types/relay.rb +10 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +54 -65
- data/readme.md +3 -6
- metadata +116 -236
- data/lib/graphql/analysis/analyze_query.rb +0 -91
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -230
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -435
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -210
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -42
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -127
- data/lib/graphql/execution/execute.rb +0 -326
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -222
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -124
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -132
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -65
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -258
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -121
- data/lib/graphql/query/arguments.rb +0 -188
- data/lib/graphql/query/arguments_cache.rb +0 -25
- data/lib/graphql/query/executor.rb +0 -53
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -39
- data/lib/graphql/relay/array_connection.rb +0 -85
- data/lib/graphql/relay/base_connection.rb +0 -176
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -41
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -105
- data/lib/graphql/relay/node.rb +0 -36
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -76
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -15
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
- data/lib/graphql/schema/member/instrumentation.rb +0 -132
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -39
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -86
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -303
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -65
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- 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
- data/lib/graphql/types/relay/node_field.rb +0 -43
- data/lib/graphql/types/relay/nodes_field.rb +0 -45
- data/lib/graphql/union_type.rb +0 -113
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
module AST
|
6
6
|
class QueryComplexity < Analyzer
|
7
7
|
# State for the query complexity calculation:
|
8
|
-
# - `complexities_on_type` holds complexity scores for each type
|
8
|
+
# - `complexities_on_type` holds complexity scores for each type
|
9
9
|
def initialize(query)
|
10
10
|
super
|
11
11
|
@complexities_on_type_by_query = {}
|
@@ -21,16 +21,24 @@ module GraphQL
|
|
21
21
|
# since the lexical binding isn't important.
|
22
22
|
HASH_CHILDREN = ->(h, k) { h[k] = {} }
|
23
23
|
|
24
|
-
|
24
|
+
attr_reader :field_definition, :response_path, :query
|
25
|
+
|
26
|
+
# @param parent_type [Class] The owner of `field_definition`
|
25
27
|
# @param field_definition [GraphQL::Field, GraphQL::Schema::Field] Used for getting the `.complexity` configuration
|
26
|
-
# @param query [
|
27
|
-
|
28
|
+
# @param query [GraphQL::Query] Used for `query.possible_types`
|
29
|
+
# @param response_path [Array<String>] The path to the response key for the field
|
30
|
+
def initialize(parent_type, field_definition, query, response_path)
|
31
|
+
@parent_type = parent_type
|
28
32
|
@field_definition = field_definition
|
29
33
|
@query = query
|
30
|
-
@
|
34
|
+
@response_path = response_path
|
31
35
|
@scoped_children = nil
|
36
|
+
@nodes = []
|
32
37
|
end
|
33
38
|
|
39
|
+
# @return [Array<GraphQL::Language::Nodes::Field>]
|
40
|
+
attr_reader :nodes
|
41
|
+
|
34
42
|
# Returns true if this field has no selections, ie, it's a scalar.
|
35
43
|
# We need a quick way to check whether we should continue traversing.
|
36
44
|
def terminal?
|
@@ -46,16 +54,7 @@ module GraphQL
|
|
46
54
|
end
|
47
55
|
|
48
56
|
def own_complexity(child_complexity)
|
49
|
-
|
50
|
-
case defined_complexity
|
51
|
-
when Proc
|
52
|
-
arguments = @query.arguments_for(@node, @field_definition)
|
53
|
-
defined_complexity.call(@query.context, arguments, child_complexity)
|
54
|
-
when Numeric
|
55
|
-
defined_complexity + child_complexity
|
56
|
-
else
|
57
|
-
raise("Invalid complexity: #{defined_complexity.inspect} on #{@field_definition.name}")
|
58
|
-
end
|
57
|
+
@field_definition.calculate_complexity(query: @query, nodes: @nodes, child_complexity: child_complexity)
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
@@ -73,9 +72,10 @@ module GraphQL
|
|
73
72
|
# `node` and `visitor.field_definition` may appear from a cache,
|
74
73
|
# but I think that's ok. If the arguments _didn't_ match,
|
75
74
|
# then the query would have been rejected as invalid.
|
76
|
-
complexities_on_type = @complexities_on_type_by_query[visitor.query] ||= [ScopedTypeComplexity.new(nil, nil, query)]
|
75
|
+
complexities_on_type = @complexities_on_type_by_query[visitor.query] ||= [ScopedTypeComplexity.new(nil, nil, query, visitor.response_path)]
|
77
76
|
|
78
|
-
complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(
|
77
|
+
complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(parent_type, visitor.field_definition, visitor.query, visitor.response_path)
|
78
|
+
complexity.nodes.push(node)
|
79
79
|
# Push it on the stack.
|
80
80
|
complexities_on_type.push(complexity)
|
81
81
|
end
|
@@ -89,132 +89,140 @@ module GraphQL
|
|
89
89
|
complexities_on_type.pop
|
90
90
|
end
|
91
91
|
|
92
|
+
private
|
93
|
+
|
92
94
|
# @return [Integer]
|
93
95
|
def max_possible_complexity
|
94
96
|
@complexities_on_type_by_query.reduce(0) do |total, (query, complexities_on_type)|
|
95
97
|
root_complexity = complexities_on_type.last
|
96
98
|
# Use this entry point to calculate the total complexity
|
97
|
-
total_complexity_for_query =
|
99
|
+
total_complexity_for_query = merged_max_complexity_for_scopes(query, [root_complexity.scoped_children])
|
98
100
|
total + total_complexity_for_query
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
def applies_to?(query, left_scope, right_scope)
|
112
|
-
if left_scope == right_scope
|
113
|
-
# This can happen when several branches are being analyzed together
|
114
|
-
true
|
115
|
-
else
|
116
|
-
# Check if these two scopes have _any_ types in common.
|
117
|
-
possible_right_types = query.possible_types(right_scope)
|
118
|
-
possible_left_types = query.possible_types(left_scope)
|
119
|
-
!(possible_right_types & possible_left_types).empty?
|
120
|
-
end
|
104
|
+
# @param query [GraphQL::Query] Used for `query.possible_types`
|
105
|
+
# @param scoped_children_hashes [Array<Hash>] Array of scoped children hashes
|
106
|
+
# @return [Integer]
|
107
|
+
def merged_max_complexity_for_scopes(query, scoped_children_hashes)
|
108
|
+
# Figure out what scopes are possible here.
|
109
|
+
# Use a hash, but ignore the values; it's just a fast way to work with the keys.
|
110
|
+
all_scopes = {}
|
111
|
+
scoped_children_hashes.each do |h|
|
112
|
+
all_scopes.merge!(h)
|
121
113
|
end
|
122
114
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
115
|
+
# If an abstract scope is present, but _all_ of its concrete types
|
116
|
+
# are also in the list, remove it from the list of scopes to check,
|
117
|
+
# because every possible type is covered by a concrete type.
|
118
|
+
# (That is, there are no remainder types to check.)
|
119
|
+
prev_keys = all_scopes.keys
|
120
|
+
prev_keys.each do |scope|
|
121
|
+
next unless scope.kind.abstract?
|
122
|
+
|
123
|
+
missing_concrete_types = query.possible_types(scope).select { |t| !all_scopes.key?(t) }
|
124
|
+
# This concrete type is possible _only_ as a member of the abstract type.
|
125
|
+
# So, attribute to it the complexity which belongs to the abstract type.
|
126
|
+
missing_concrete_types.each do |concrete_scope|
|
127
|
+
all_scopes[concrete_scope] = all_scopes[scope]
|
129
128
|
end
|
129
|
+
all_scopes.delete(scope)
|
130
|
+
end
|
130
131
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
132
|
+
# This will hold `{ type => int }` pairs, one for each possible branch
|
133
|
+
complexity_by_scope = {}
|
134
|
+
|
135
|
+
# For each scope,
|
136
|
+
# find the lexical selections that might apply to it,
|
137
|
+
# and gather them together into an array.
|
138
|
+
# Then, treat the set of selection hashes
|
139
|
+
# as a set and calculate the complexity for them as a unit
|
140
|
+
all_scopes.each do |scope, _|
|
141
|
+
# These will be the selections on `scope`
|
142
|
+
children_for_scope = []
|
143
|
+
scoped_children_hashes.each do |sc_h|
|
144
|
+
sc_h.each do |inner_scope, children_hash|
|
145
|
+
if applies_to?(query, scope, inner_scope)
|
146
|
+
children_for_scope << children_hash
|
145
147
|
end
|
146
|
-
all_scopes.delete(scope)
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
150
|
-
#
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
# and gather them together into an array.
|
156
|
-
# Then, treat the set of selection hashes
|
157
|
-
# as a set and calculate the complexity for them as a unit
|
158
|
-
all_scopes.each do |scope, _|
|
159
|
-
# These will be the selections on `scope`
|
160
|
-
children_for_scope = []
|
161
|
-
scoped_children_hashes.each do |sc_h|
|
162
|
-
sc_h.each do |inner_scope, children_hash|
|
163
|
-
if applies_to?(query, scope, inner_scope)
|
164
|
-
children_for_scope << children_hash
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
151
|
+
# Calculate the complexity for `scope`, merging all
|
152
|
+
# possible lexical branches.
|
153
|
+
complexity_value = merged_max_complexity(query, children_for_scope)
|
154
|
+
complexity_by_scope[scope] = complexity_value
|
155
|
+
end
|
168
156
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
complexity_by_scope[scope] = complexity_value
|
173
|
-
end
|
157
|
+
# Return the max complexity among all scopes
|
158
|
+
complexity_by_scope.each_value.max
|
159
|
+
end
|
174
160
|
|
175
|
-
|
176
|
-
|
161
|
+
def applies_to?(query, left_scope, right_scope)
|
162
|
+
if left_scope == right_scope
|
163
|
+
# This can happen when several branches are being analyzed together
|
164
|
+
true
|
165
|
+
else
|
166
|
+
# Check if these two scopes have _any_ types in common.
|
167
|
+
possible_right_types = query.possible_types(right_scope)
|
168
|
+
possible_left_types = query.possible_types(left_scope)
|
169
|
+
!(possible_right_types & possible_left_types).empty?
|
177
170
|
end
|
171
|
+
end
|
178
172
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
complexity_for_keys = {}
|
188
|
-
all_keys.each do |child_key|
|
189
|
-
|
190
|
-
scoped_children_for_key = nil
|
191
|
-
complexity_for_key = nil
|
192
|
-
children_for_scope.each do |children_hash|
|
193
|
-
if children_hash.key?(child_key)
|
194
|
-
complexity_for_key = children_hash[child_key]
|
195
|
-
if complexity_for_key.terminal?
|
196
|
-
# Assume that all terminals would return the same complexity
|
197
|
-
# Since it's a terminal, its child complexity is zero.
|
198
|
-
complexity_for_key = complexity_for_key.own_complexity(0)
|
199
|
-
complexity_for_keys[child_key] = complexity_for_key
|
200
|
-
else
|
201
|
-
scoped_children_for_key ||= []
|
202
|
-
scoped_children_for_key << complexity_for_key.scoped_children
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
173
|
+
# A hook which is called whenever a field's max complexity is calculated.
|
174
|
+
# Override this method to capture individual field complexity details.
|
175
|
+
#
|
176
|
+
# @param scoped_type_complexity [ScopedTypeComplexity]
|
177
|
+
# @param max_complexity [Numeric] Field's maximum complexity including child complexity
|
178
|
+
# @param child_complexity [Numeric, nil] Field's child complexity
|
179
|
+
def field_complexity(scoped_type_complexity, max_complexity:, child_complexity: nil)
|
180
|
+
end
|
206
181
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
182
|
+
# @param children_for_scope [Array<Hash>] An array of `scoped_children[scope]` hashes
|
183
|
+
# (`{field_key => complexity}`)
|
184
|
+
# @return [Integer] Complexity value for all these selections in the current scope
|
185
|
+
def merged_max_complexity(query, children_for_scope)
|
186
|
+
all_keys = []
|
187
|
+
children_for_scope.each do |c|
|
188
|
+
all_keys.concat(c.keys)
|
189
|
+
end
|
190
|
+
all_keys.uniq!
|
191
|
+
complexity_for_keys = {}
|
192
|
+
|
193
|
+
all_keys.each do |child_key|
|
194
|
+
scoped_children_for_key = nil
|
195
|
+
complexity_for_key = nil
|
196
|
+
children_for_scope.each do |children_hash|
|
197
|
+
next unless children_hash.key?(child_key)
|
198
|
+
|
199
|
+
complexity_for_key = children_hash[child_key]
|
200
|
+
if complexity_for_key.terminal?
|
201
|
+
# Assume that all terminals would return the same complexity
|
202
|
+
# Since it's a terminal, its child complexity is zero.
|
203
|
+
complexity = complexity_for_key.own_complexity(0)
|
204
|
+
complexity_for_keys[child_key] = complexity
|
205
|
+
|
206
|
+
field_complexity(complexity_for_key, max_complexity: complexity, child_complexity: nil)
|
207
|
+
else
|
208
|
+
scoped_children_for_key ||= []
|
209
|
+
scoped_children_for_key << complexity_for_key.scoped_children
|
212
210
|
end
|
213
211
|
end
|
214
212
|
|
215
|
-
|
216
|
-
|
213
|
+
next unless scoped_children_for_key
|
214
|
+
|
215
|
+
child_complexity = merged_max_complexity_for_scopes(query, scoped_children_for_key)
|
216
|
+
# This is the _last_ one we visited; assume it's representative.
|
217
|
+
max_complexity = complexity_for_key.own_complexity(child_complexity)
|
218
|
+
|
219
|
+
field_complexity(complexity_for_key, max_complexity: max_complexity, child_complexity: child_complexity)
|
220
|
+
|
221
|
+
complexity_for_keys[child_key] = max_complexity
|
217
222
|
end
|
223
|
+
|
224
|
+
# Calculate the child complexity by summing the complexity of all selections
|
225
|
+
complexity_for_keys.each_value.inject(0, &:+)
|
218
226
|
end
|
219
227
|
end
|
220
228
|
end
|
@@ -19,6 +19,7 @@ module GraphQL
|
|
19
19
|
@field_definitions = []
|
20
20
|
@argument_definitions = []
|
21
21
|
@directive_definitions = []
|
22
|
+
@rescued_errors = []
|
22
23
|
@query = query
|
23
24
|
@schema = query.schema
|
24
25
|
@response_path = []
|
@@ -32,6 +33,9 @@ module GraphQL
|
|
32
33
|
# @return [Array<GraphQL::ObjectType>] Types whose scope we've entered
|
33
34
|
attr_reader :object_types
|
34
35
|
|
36
|
+
# @return [Array<GraphQL::AnalysisError]
|
37
|
+
attr_reader :rescued_errors
|
38
|
+
|
35
39
|
def visit
|
36
40
|
return unless @document
|
37
41
|
super
|
@@ -39,7 +43,7 @@ module GraphQL
|
|
39
43
|
|
40
44
|
# Visit Helpers
|
41
45
|
|
42
|
-
# @return [GraphQL::
|
46
|
+
# @return [GraphQL::Execution::Interpreter::Arguments] Arguments for this node, merging default values, literal values and query variables
|
43
47
|
# @see {GraphQL::Query#arguments_for}
|
44
48
|
def arguments_for(ast_node, field_definition)
|
45
49
|
@query.arguments_for(ast_node, field_definition)
|
@@ -61,14 +65,41 @@ module GraphQL
|
|
61
65
|
end
|
62
66
|
|
63
67
|
# Visitor Hooks
|
68
|
+
[
|
69
|
+
:operation_definition, :fragment_definition,
|
70
|
+
:inline_fragment, :field, :directive, :argument, :fragment_spread
|
71
|
+
].each do |node_type|
|
72
|
+
module_eval <<-RUBY, __FILE__, __LINE__
|
73
|
+
def call_on_enter_#{node_type}(node, parent)
|
74
|
+
@analyzers.each do |a|
|
75
|
+
begin
|
76
|
+
a.on_enter_#{node_type}(node, parent, self)
|
77
|
+
rescue AnalysisError => err
|
78
|
+
@rescued_errors << err
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def call_on_leave_#{node_type}(node, parent)
|
84
|
+
@analyzers.each do |a|
|
85
|
+
begin
|
86
|
+
a.on_leave_#{node_type}(node, parent, self)
|
87
|
+
rescue AnalysisError => err
|
88
|
+
@rescued_errors << err
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
RUBY
|
94
|
+
end
|
64
95
|
|
65
96
|
def on_operation_definition(node, parent)
|
66
97
|
object_type = @schema.root_type_for_operation(node.operation_type)
|
67
98
|
@object_types.push(object_type)
|
68
99
|
@path.push("#{node.operation_type}#{node.name ? " #{node.name}" : ""}")
|
69
|
-
|
100
|
+
call_on_enter_operation_definition(node, parent)
|
70
101
|
super
|
71
|
-
|
102
|
+
call_on_leave_operation_definition(node, parent)
|
72
103
|
@object_types.pop
|
73
104
|
@path.pop
|
74
105
|
end
|
@@ -77,26 +108,27 @@ module GraphQL
|
|
77
108
|
on_fragment_with_type(node) do
|
78
109
|
@path.push("fragment #{node.name}")
|
79
110
|
@in_fragment_def = false
|
80
|
-
|
111
|
+
call_on_enter_fragment_definition(node, parent)
|
81
112
|
super
|
82
113
|
@in_fragment_def = false
|
83
|
-
|
114
|
+
call_on_leave_fragment_definition(node, parent)
|
84
115
|
end
|
85
116
|
end
|
86
117
|
|
87
118
|
def on_inline_fragment(node, parent)
|
88
119
|
on_fragment_with_type(node) do
|
89
120
|
@path.push("...#{node.type ? " on #{node.type.name}" : ""}")
|
90
|
-
|
121
|
+
call_on_enter_inline_fragment(node, parent)
|
91
122
|
super
|
92
|
-
|
123
|
+
call_on_leave_inline_fragment(node, parent)
|
93
124
|
end
|
94
125
|
end
|
95
126
|
|
96
127
|
def on_field(node, parent)
|
97
128
|
@response_path.push(node.alias || node.name)
|
98
129
|
parent_type = @object_types.last
|
99
|
-
|
130
|
+
# This could be nil if the previous field wasn't found:
|
131
|
+
field_definition = parent_type && @schema.get_field(parent_type, node.name, @query.context)
|
100
132
|
@field_definitions.push(field_definition)
|
101
133
|
if !field_definition.nil?
|
102
134
|
next_object_type = field_definition.type.unwrap
|
@@ -109,12 +141,10 @@ module GraphQL
|
|
109
141
|
@skipping = @skip_stack.last || skip?(node)
|
110
142
|
@skip_stack << @skipping
|
111
143
|
|
112
|
-
|
144
|
+
call_on_enter_field(node, parent)
|
113
145
|
super
|
114
|
-
|
115
146
|
@skipping = @skip_stack.pop
|
116
|
-
|
117
|
-
call_analyzers(:on_leave_field, node, parent)
|
147
|
+
call_on_leave_field(node, parent)
|
118
148
|
@response_path.pop
|
119
149
|
@field_definitions.pop
|
120
150
|
@object_types.pop
|
@@ -124,9 +154,9 @@ module GraphQL
|
|
124
154
|
def on_directive(node, parent)
|
125
155
|
directive_defn = @schema.directives[node.name]
|
126
156
|
@directive_definitions.push(directive_defn)
|
127
|
-
|
157
|
+
call_on_enter_directive(node, parent)
|
128
158
|
super
|
129
|
-
|
159
|
+
call_on_leave_directive(node, parent)
|
130
160
|
@directive_definitions.pop
|
131
161
|
end
|
132
162
|
|
@@ -134,43 +164,37 @@ module GraphQL
|
|
134
164
|
argument_defn = if (arg = @argument_definitions.last)
|
135
165
|
arg_type = arg.type.unwrap
|
136
166
|
if arg_type.kind.input_object?
|
137
|
-
arg_type.
|
167
|
+
arg_type.get_argument(node.name, @query.context)
|
138
168
|
else
|
139
169
|
nil
|
140
170
|
end
|
141
171
|
elsif (directive_defn = @directive_definitions.last)
|
142
|
-
directive_defn.
|
172
|
+
directive_defn.get_argument(node.name, @query.context)
|
143
173
|
elsif (field_defn = @field_definitions.last)
|
144
|
-
field_defn.
|
174
|
+
field_defn.get_argument(node.name, @query.context)
|
145
175
|
else
|
146
176
|
nil
|
147
177
|
end
|
148
178
|
|
149
179
|
@argument_definitions.push(argument_defn)
|
150
180
|
@path.push(node.name)
|
151
|
-
|
181
|
+
call_on_enter_argument(node, parent)
|
152
182
|
super
|
153
|
-
|
183
|
+
call_on_leave_argument(node, parent)
|
154
184
|
@argument_definitions.pop
|
155
185
|
@path.pop
|
156
186
|
end
|
157
187
|
|
158
188
|
def on_fragment_spread(node, parent)
|
159
189
|
@path.push("... #{node.name}")
|
160
|
-
|
190
|
+
call_on_enter_fragment_spread(node, parent)
|
161
191
|
enter_fragment_spread_inline(node)
|
162
192
|
super
|
163
193
|
leave_fragment_spread_inline(node)
|
164
|
-
|
194
|
+
call_on_leave_fragment_spread(node, parent)
|
165
195
|
@path.pop
|
166
196
|
end
|
167
197
|
|
168
|
-
def on_abstract_node(node, parent)
|
169
|
-
call_analyzers(:on_enter_abstract_node, node, parent)
|
170
|
-
super
|
171
|
-
call_analyzers(:on_leave_abstract_node, node, parent)
|
172
|
-
end
|
173
|
-
|
174
198
|
# @return [GraphQL::BaseType] The current object type
|
175
199
|
def type_definition
|
176
200
|
@object_types.last
|
@@ -221,9 +245,7 @@ module GraphQL
|
|
221
245
|
|
222
246
|
object_types << object_type
|
223
247
|
|
224
|
-
fragment_def
|
225
|
-
visit_node(selection, fragment_def)
|
226
|
-
end
|
248
|
+
on_fragment_definition_children(fragment_def)
|
227
249
|
end
|
228
250
|
|
229
251
|
# Visit a fragment spread inline instead of visiting the definition
|
@@ -237,12 +259,6 @@ module GraphQL
|
|
237
259
|
dir.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
|
238
260
|
end
|
239
261
|
|
240
|
-
def call_analyzers(method, node, parent)
|
241
|
-
@analyzers.each do |analyzer|
|
242
|
-
analyzer.public_send(method, node, parent, self)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
262
|
def on_fragment_with_type(node)
|
247
263
|
object_type = if node.type
|
248
264
|
@query.warden.get_type(node.type.name)
|
data/lib/graphql/analysis/ast.rb
CHANGED
@@ -11,11 +11,6 @@ module GraphQL
|
|
11
11
|
module Analysis
|
12
12
|
module AST
|
13
13
|
module_function
|
14
|
-
|
15
|
-
def use(schema_class)
|
16
|
-
schema_class.analysis_engine = GraphQL::Analysis::AST
|
17
|
-
end
|
18
|
-
|
19
14
|
# Analyze a multiplex, and all queries within.
|
20
15
|
# Multiplex analyzers are ran for all queries, keeping state.
|
21
16
|
# Query analyzers are ran per query, without carrying state between queries.
|
@@ -26,7 +21,7 @@ module GraphQL
|
|
26
21
|
def analyze_multiplex(multiplex, analyzers)
|
27
22
|
multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
|
28
23
|
|
29
|
-
multiplex.
|
24
|
+
multiplex.current_trace.analyze_multiplex(multiplex: multiplex) do
|
30
25
|
query_results = multiplex.queries.map do |query|
|
31
26
|
if query.valid?
|
32
27
|
analyze_query(
|
@@ -53,7 +48,7 @@ module GraphQL
|
|
53
48
|
# @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
|
54
49
|
# @return [Array<Any>] Results from those analyzers
|
55
50
|
def analyze_query(query, analyzers, multiplex_analyzers: [])
|
56
|
-
query.
|
51
|
+
query.current_trace.analyze_query(query: query) do
|
57
52
|
query_analyzers = analyzers
|
58
53
|
.map { |analyzer| analyzer.new(query) }
|
59
54
|
.select { |analyzer| analyzer.analyze? }
|
@@ -67,7 +62,11 @@ module GraphQL
|
|
67
62
|
|
68
63
|
visitor.visit
|
69
64
|
|
70
|
-
|
65
|
+
if visitor.rescued_errors.any?
|
66
|
+
visitor.rescued_errors
|
67
|
+
else
|
68
|
+
query_analyzers.map(&:result)
|
69
|
+
end
|
71
70
|
else
|
72
71
|
[]
|
73
72
|
end
|
data/lib/graphql/analysis.rb
CHANGED
@@ -1,9 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/analysis/ast"
|
3
|
-
require "graphql/analysis/max_query_complexity"
|
4
|
-
require "graphql/analysis/max_query_depth"
|
5
|
-
require "graphql/analysis/query_complexity"
|
6
|
-
require "graphql/analysis/query_depth"
|
7
|
-
require "graphql/analysis/reducer_state"
|
8
|
-
require "graphql/analysis/analyze_query"
|
9
|
-
require "graphql/analysis/field_usage"
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# test_via: ../backtrace.rb
|
3
2
|
module GraphQL
|
4
3
|
class Backtrace
|
5
4
|
# A class for turning a context into a human-readable table or array
|
@@ -79,24 +78,25 @@ module GraphQL
|
|
79
78
|
# @return [Array] 5 items for a backtrace table (not `key`)
|
80
79
|
def build_rows(context_entry, rows:, top: false)
|
81
80
|
case context_entry
|
82
|
-
when
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
if object.is_a?(GraphQL::Schema::Object)
|
89
|
-
object = object.object
|
81
|
+
when Backtrace::Frame
|
82
|
+
field_alias = context_entry.ast_node.respond_to?(:alias) && context_entry.ast_node.alias
|
83
|
+
value = if top && @override_value
|
84
|
+
@override_value
|
85
|
+
else
|
86
|
+
value_at(@context.query.context.namespace(:interpreter_runtime)[:runtime], context_entry.path)
|
90
87
|
end
|
91
88
|
rows << [
|
92
|
-
"#{position}",
|
93
|
-
"#{
|
94
|
-
"#{object.inspect}",
|
95
|
-
|
96
|
-
Backtrace::InspectResult.inspect_result(
|
89
|
+
"#{context_entry.ast_node ? context_entry.ast_node.position.join(":") : ""}",
|
90
|
+
"#{context_entry.field.path}#{field_alias ? " as #{field_alias}" : ""}",
|
91
|
+
"#{context_entry.object.object.inspect}",
|
92
|
+
context_entry.arguments.to_h.inspect, # rubocop:disable Development/ContextIsPassedCop -- unrelated method
|
93
|
+
Backtrace::InspectResult.inspect_result(value),
|
97
94
|
]
|
98
|
-
|
99
|
-
|
95
|
+
if (parent = context_entry.parent_frame)
|
96
|
+
build_rows(parent, rows: rows)
|
97
|
+
else
|
98
|
+
rows
|
99
|
+
end
|
100
100
|
when GraphQL::Query::Context
|
101
101
|
query = context_entry.query
|
102
102
|
op = query.selected_operation
|
@@ -112,16 +112,29 @@ module GraphQL
|
|
112
112
|
if object.is_a?(GraphQL::Schema::Object)
|
113
113
|
object = object.object
|
114
114
|
end
|
115
|
+
value = value_at(context_entry.namespace(:interpreter_runtime)[:runtime], [])
|
115
116
|
rows << [
|
116
117
|
"#{position}",
|
117
118
|
"#{op_type}#{op_name ? " #{op_name}" : ""}",
|
118
119
|
"#{object.inspect}",
|
119
120
|
query.variables.to_h.inspect,
|
120
|
-
Backtrace::InspectResult.inspect_result(
|
121
|
+
Backtrace::InspectResult.inspect_result(value),
|
121
122
|
]
|
122
123
|
else
|
123
|
-
raise "Unexpected get_rows subject #{context_entry.inspect}"
|
124
|
+
raise "Unexpected get_rows subject #{context_entry.class} (#{context_entry.inspect})"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def value_at(runtime, path)
|
129
|
+
response = runtime.final_result
|
130
|
+
path.each do |key|
|
131
|
+
if response && (response = response[key])
|
132
|
+
next
|
133
|
+
else
|
134
|
+
break
|
135
|
+
end
|
124
136
|
end
|
137
|
+
response
|
125
138
|
end
|
126
139
|
end
|
127
140
|
end
|