graphql 1.9.17 → 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 +25 -27
- 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 +31 -2
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +54 -38
- data/lib/graphql/analysis/ast.rb +16 -16
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +37 -16
- 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/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +77 -45
- 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 +830 -417
- data/lib/graphql/execution/interpreter.rb +206 -74
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +65 -136
- data/lib/graphql/execution/multiplex.rb +6 -152
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +8 -3
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/base_object.rb +2 -5
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +12 -6
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +5 -18
- 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 +41 -11
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +12 -12
- data/lib/graphql/introspection/type_type.rb +34 -17
- 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/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +136 -78
- data/lib/graphql/language/lexer.rb +216 -1462
- data/lib/graphql/language/nodes.rb +129 -132
- data/lib/graphql/language/parser.rb +994 -932
- data/lib/graphql/language/parser.y +152 -120
- 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 +3 -1
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +77 -0
- data/lib/graphql/pagination/array_connection.rb +79 -0
- data/lib/graphql/pagination/connection.rb +253 -0
- data/lib/graphql/pagination/connections.rb +135 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +228 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +205 -203
- 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 +39 -12
- data/lib/graphql/query.rb +95 -43
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +4 -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 +285 -36
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
- data/lib/graphql/schema/build_from_definition.rb +348 -205
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- 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 +2 -2
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +2 -2
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +134 -15
- data/lib/graphql/schema/enum.rb +137 -39
- data/lib/graphql/schema/enum_value.rb +17 -23
- data/lib/graphql/schema/field/connection_extension.rb +50 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +504 -331
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +12 -1
- data/lib/graphql/schema/finder.rb +16 -14
- data/lib/graphql/schema/input_object.rb +182 -60
- data/lib/graphql/schema/interface.rb +24 -49
- data/lib/graphql/schema/introspection_system.rb +103 -37
- data/lib/graphql/schema/late_bound_type.rb +9 -2
- data/lib/graphql/schema/list.rb +61 -3
- data/lib/graphql/schema/loader.rb +144 -96
- data/lib/graphql/schema/member/base_dsl_methods.rb +41 -37
- data/lib/graphql/schema/member/build_type.rb +24 -15
- data/lib/graphql/schema/member/has_arguments.rb +310 -26
- data/lib/graphql/schema/member/has_ast_node.rb +32 -0
- 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 +166 -44
- 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 +33 -0
- data/lib/graphql/schema/member.rb +11 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +34 -4
- data/lib/graphql/schema/object.rb +36 -60
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +91 -44
- data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
- data/lib/graphql/schema/resolver.rb +147 -94
- data/lib/graphql/schema/scalar.rb +40 -15
- data/lib/graphql/schema/subscription.rb +60 -31
- data/lib/graphql/schema/timeout.rb +45 -35
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +23 -6
- data/lib/graphql/schema/union.rb +49 -15
- 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 +213 -35
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +857 -884
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +21 -31
- 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 +45 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
- 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 +14 -14
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +15 -7
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +96 -53
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- 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 +9 -10
- 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 +12 -13
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
- data/lib/graphql/static_validation/type_stack.rb +2 -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 +129 -22
- 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 +84 -35
- data/lib/graphql/subscriptions/instrumentation.rb +0 -47
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +137 -57
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
- 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 +23 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +34 -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 +9 -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 +76 -35
- 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 +11 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -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 -67
- 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 -90
- 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/unresolved_type_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +63 -65
- data/readme.md +3 -6
- metadata +127 -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 -159
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -226
- 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 -91
- 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 -50
- data/lib/graphql/define/instance_definable.rb +0 -300
- 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 -13
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -104
- data/lib/graphql/enum_type.rb +0 -193
- 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 -330
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -153
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -154
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -86
- 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 -81
- data/lib/graphql/object_type.rb +0 -141
- data/lib/graphql/query/arguments.rb +0 -187
- 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 -116
- 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 -172
- 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 -40
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -18
- 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 -190
- 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 -133
- 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 -26
- 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 -66
- data/lib/graphql/tracing/skylight_tracing.rb +0 -62
- 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 -128
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -5,10 +5,10 @@ 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 = {}
|
12
12
|
end
|
13
13
|
|
14
14
|
# Overide this method to use the complexity result
|
@@ -16,17 +16,68 @@ module GraphQL
|
|
16
16
|
max_possible_complexity
|
17
17
|
end
|
18
18
|
|
19
|
+
class ScopedTypeComplexity
|
20
|
+
# A single proc for {#scoped_children} hashes. Use this to avoid repeated allocations,
|
21
|
+
# since the lexical binding isn't important.
|
22
|
+
HASH_CHILDREN = ->(h, k) { h[k] = {} }
|
23
|
+
|
24
|
+
attr_reader :field_definition, :response_path, :query
|
25
|
+
|
26
|
+
# @param parent_type [Class] The owner of `field_definition`
|
27
|
+
# @param field_definition [GraphQL::Field, GraphQL::Schema::Field] Used for getting the `.complexity` configuration
|
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
|
32
|
+
@field_definition = field_definition
|
33
|
+
@query = query
|
34
|
+
@response_path = response_path
|
35
|
+
@scoped_children = nil
|
36
|
+
@nodes = []
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array<GraphQL::Language::Nodes::Field>]
|
40
|
+
attr_reader :nodes
|
41
|
+
|
42
|
+
# Returns true if this field has no selections, ie, it's a scalar.
|
43
|
+
# We need a quick way to check whether we should continue traversing.
|
44
|
+
def terminal?
|
45
|
+
@scoped_children.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# This value is only calculated when asked for to avoid needless hash allocations.
|
49
|
+
# Also, if it's never asked for, we determine that this scope complexity
|
50
|
+
# is a scalar field ({#terminal?}).
|
51
|
+
# @return [Hash<Hash<Class => ScopedTypeComplexity>]
|
52
|
+
def scoped_children
|
53
|
+
@scoped_children ||= Hash.new(&HASH_CHILDREN)
|
54
|
+
end
|
55
|
+
|
56
|
+
def own_complexity(child_complexity)
|
57
|
+
@field_definition.calculate_complexity(query: @query, nodes: @nodes, child_complexity: child_complexity)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
19
61
|
def on_enter_field(node, parent, visitor)
|
20
62
|
# We don't want to visit fragment definitions,
|
21
63
|
# we'll visit them when we hit the spreads instead
|
22
64
|
return if visitor.visiting_fragment_definition?
|
23
65
|
return if visitor.skipping?
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
66
|
+
parent_type = visitor.parent_type_definition
|
67
|
+
field_key = node.alias || node.name
|
68
|
+
# Find the complexity calculation for this field --
|
69
|
+
# if we're re-entering a selection, we'll already have one.
|
70
|
+
# Otherwise, make a new one and store it.
|
71
|
+
#
|
72
|
+
# `node` and `visitor.field_definition` may appear from a cache,
|
73
|
+
# but I think that's ok. If the arguments _didn't_ match,
|
74
|
+
# then the query would have been rejected as invalid.
|
75
|
+
complexities_on_type = @complexities_on_type_by_query[visitor.query] ||= [ScopedTypeComplexity.new(nil, nil, query, visitor.response_path)]
|
76
|
+
|
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
|
+
# Push it on the stack.
|
80
|
+
complexities_on_type.push(complexity)
|
30
81
|
end
|
31
82
|
|
32
83
|
def on_leave_field(node, parent, visitor)
|
@@ -34,88 +85,144 @@ module GraphQL
|
|
34
85
|
# we'll visit them when we hit the spreads instead
|
35
86
|
return if visitor.visiting_fragment_definition?
|
36
87
|
return if visitor.skipping?
|
88
|
+
complexities_on_type = @complexities_on_type_by_query[visitor.query]
|
89
|
+
complexities_on_type.pop
|
90
|
+
end
|
37
91
|
|
38
|
-
|
39
|
-
child_complexity = type_complexities.max_possible_complexity
|
40
|
-
own_complexity = get_complexity(node, visitor.field_definition, child_complexity, visitor)
|
92
|
+
private
|
41
93
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
@complexities_on_type.last.merge(own_complexity)
|
94
|
+
# @return [Integer]
|
95
|
+
def max_possible_complexity
|
96
|
+
@complexities_on_type_by_query.reduce(0) do |total, (query, complexities_on_type)|
|
97
|
+
root_complexity = complexities_on_type.last
|
98
|
+
# Use this entry point to calculate the total complexity
|
99
|
+
total_complexity_for_query = merged_max_complexity_for_scopes(query, [root_complexity.scoped_children])
|
100
|
+
total + total_complexity_for_query
|
50
101
|
end
|
51
102
|
end
|
52
103
|
|
104
|
+
# @param query [GraphQL::Query] Used for `query.possible_types`
|
105
|
+
# @param scoped_children_hashes [Array<Hash>] Array of scoped children hashes
|
53
106
|
# @return [Integer]
|
54
|
-
def
|
55
|
-
|
56
|
-
|
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)
|
113
|
+
end
|
57
114
|
|
58
|
-
|
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]
|
128
|
+
end
|
129
|
+
all_scopes.delete(scope)
|
130
|
+
end
|
59
131
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
#
|
64
|
-
|
65
|
-
|
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
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
66
150
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
72
156
|
|
73
|
-
|
157
|
+
# Return the max complexity among all scopes
|
158
|
+
complexity_by_scope.each_value.max
|
159
|
+
end
|
74
160
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
defined_complexity + (child_complexity || 0)
|
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
|
80
165
|
else
|
81
|
-
|
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?
|
82
170
|
end
|
83
171
|
end
|
84
172
|
|
85
|
-
#
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
91
181
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
max
|
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)
|
100
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
|
210
|
+
end
|
211
|
+
end
|
101
212
|
|
102
|
-
|
103
|
-
# Later we will see if this is the max complexity among branches.
|
104
|
-
def merge(type_defn, key, complexity)
|
105
|
-
@types[type_defn][key] = complexity
|
106
|
-
end
|
107
|
-
end
|
213
|
+
next unless scoped_children_for_key
|
108
214
|
|
109
|
-
|
110
|
-
|
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)
|
111
218
|
|
112
|
-
|
113
|
-
@max_possible_complexity = 0
|
114
|
-
end
|
219
|
+
field_complexity(complexity_for_key, max_complexity: max_complexity, child_complexity: child_complexity)
|
115
220
|
|
116
|
-
|
117
|
-
@max_possible_complexity += complexity
|
221
|
+
complexity_for_keys[child_key] = max_complexity
|
118
222
|
end
|
223
|
+
|
224
|
+
# Calculate the child complexity by summing the complexity of all selections
|
225
|
+
complexity_for_keys.each_value.inject(0, &:+)
|
119
226
|
end
|
120
227
|
end
|
121
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
|
@@ -214,16 +238,14 @@ module GraphQL
|
|
214
238
|
fragment_def = query.fragments[fragment_spread.name]
|
215
239
|
|
216
240
|
object_type = if fragment_def.type
|
217
|
-
query.
|
241
|
+
@query.warden.get_type(fragment_def.type.name)
|
218
242
|
else
|
219
243
|
object_types.last
|
220
244
|
end
|
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,15 +259,9 @@ 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)
|
249
265
|
else
|
250
266
|
@object_types.last
|
251
267
|
end
|
data/lib/graphql/analysis/ast.rb
CHANGED
@@ -11,12 +11,6 @@ module GraphQL
|
|
11
11
|
module Analysis
|
12
12
|
module AST
|
13
13
|
module_function
|
14
|
-
|
15
|
-
def use(schema_defn)
|
16
|
-
schema = schema_defn.target
|
17
|
-
schema.analysis_engine = GraphQL::Analysis::AST
|
18
|
-
end
|
19
|
-
|
20
14
|
# Analyze a multiplex, and all queries within.
|
21
15
|
# Multiplex analyzers are ran for all queries, keeping state.
|
22
16
|
# Query analyzers are ran per query, without carrying state between queries.
|
@@ -27,7 +21,7 @@ module GraphQL
|
|
27
21
|
def analyze_multiplex(multiplex, analyzers)
|
28
22
|
multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
|
29
23
|
|
30
|
-
multiplex.
|
24
|
+
multiplex.current_trace.analyze_multiplex(multiplex: multiplex) do
|
31
25
|
query_results = multiplex.queries.map do |query|
|
32
26
|
if query.valid?
|
33
27
|
analyze_query(
|
@@ -54,22 +48,28 @@ module GraphQL
|
|
54
48
|
# @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
|
55
49
|
# @return [Array<Any>] Results from those analyzers
|
56
50
|
def analyze_query(query, analyzers, multiplex_analyzers: [])
|
57
|
-
query.
|
51
|
+
query.current_trace.analyze_query(query: query) do
|
58
52
|
query_analyzers = analyzers
|
59
53
|
.map { |analyzer| analyzer.new(query) }
|
60
54
|
.select { |analyzer| analyzer.analyze? }
|
61
55
|
|
62
56
|
analyzers_to_run = query_analyzers + multiplex_analyzers
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
)
|
57
|
+
if analyzers_to_run.any?
|
58
|
+
visitor = GraphQL::Analysis::AST::Visitor.new(
|
59
|
+
query: query,
|
60
|
+
analyzers: analyzers_to_run
|
61
|
+
)
|
69
62
|
|
70
|
-
|
63
|
+
visitor.visit
|
71
64
|
|
72
|
-
|
65
|
+
if visitor.rescued_errors.any?
|
66
|
+
visitor.rescued_errors
|
67
|
+
else
|
68
|
+
query_analyzers.map(&:result)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
[]
|
72
|
+
end
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
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"
|