graphql 1.12.12 → 2.2.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.
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 +3 -8
- 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 +14 -4
- data/lib/generators/graphql/interface_generator.rb +7 -7
- 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 +5 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +10 -38
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +23 -12
- 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 +2 -0
- data/lib/generators/graphql/templates/base_edge.erb +2 -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_resolver.erb +6 -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 +5 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +4 -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 +2 -0
- data/lib/generators/graphql/templates/object.erb +4 -2
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/scalar.erb +3 -1
- data/lib/generators/graphql/templates/schema.erb +19 -2
- data/lib/generators/graphql/templates/union.erb +4 -2
- data/lib/generators/graphql/type_generator.rb +46 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/analyzer.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +55 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +88 -140
- data/lib/graphql/analysis/ast/query_depth.rb +7 -3
- data/lib/graphql/analysis/ast/visitor.rb +50 -42
- data/lib/graphql/analysis/ast.rb +26 -23
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +4 -22
- data/lib/graphql/backtrace/trace.rb +93 -0
- data/lib/graphql/backtrace/tracer.rb +8 -6
- data/lib/graphql/backtrace.rb +3 -8
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/dataloader/async_dataloader.rb +85 -0
- data/lib/graphql/dataloader/null_dataloader.rb +3 -1
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/dataloader/source.rb +120 -31
- data/lib/graphql/dataloader.rb +168 -142
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/duration_encoding_error.rb +16 -0
- data/lib/graphql/execution/errors.rb +12 -81
- data/lib/graphql/execution/interpreter/arguments.rb +2 -2
- data/lib/graphql/execution/interpreter/arguments_cache.rb +36 -34
- data/lib/graphql/execution/interpreter/resolve.rb +32 -2
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
- data/lib/graphql/execution/interpreter/runtime.rb +414 -341
- data/lib/graphql/execution/interpreter.rb +122 -80
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +125 -54
- data/lib/graphql/execution/multiplex.rb +4 -172
- data/lib/graphql/execution.rb +11 -4
- 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 +5 -3
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +11 -18
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +3 -3
- data/lib/graphql/introspection/input_value_type.rb +10 -4
- data/lib/graphql/introspection/schema_type.rb +12 -5
- data/lib/graphql/introspection/type_type.rb +25 -12
- data/lib/graphql/introspection.rb +6 -2
- data/lib/graphql/language/block_string.rb +37 -25
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +78 -65
- data/lib/graphql/language/lexer.rb +345 -1467
- data/lib/graphql/language/nodes.rb +145 -91
- data/lib/graphql/language/parser.rb +701 -1921
- data/lib/graphql/language/printer.rb +351 -155
- data/lib/graphql/language/sanitized_printer.rb +25 -27
- data/lib/graphql/language/static_visitor.rb +167 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +188 -141
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/load_application_object_failed_error.rb +5 -1
- data/lib/graphql/name_validator.rb +0 -4
- data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
- data/lib/graphql/pagination/array_connection.rb +8 -6
- data/lib/graphql/pagination/connection.rb +61 -7
- data/lib/graphql/pagination/connections.rb +22 -23
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
- data/lib/graphql/pagination/relation_connection.rb +60 -28
- data/lib/graphql/query/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +109 -189
- data/lib/graphql/query/input_validation_result.rb +10 -1
- data/lib/graphql/query/null_context.rb +14 -29
- data/lib/graphql/query/validation_pipeline.rb +15 -39
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +35 -17
- data/lib/graphql/query.rb +78 -65
- data/lib/graphql/railtie.rb +8 -109
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +30 -11
- data/lib/graphql/relay/range_add.rb +9 -16
- 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 +78 -45
- data/lib/graphql/schema/always_visible.rb +10 -0
- data/lib/graphql/schema/argument.rb +134 -80
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +60 -38
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/one_of.rb +24 -0
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive/transform.rb +2 -2
- data/lib/graphql/schema/directive.rb +33 -21
- data/lib/graphql/schema/enum.rb +93 -46
- data/lib/graphql/schema/enum_value.rb +4 -21
- data/lib/graphql/schema/field/connection_extension.rb +6 -16
- data/lib/graphql/schema/field/scope_extension.rb +8 -1
- data/lib/graphql/schema/field.rb +432 -337
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +3 -7
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/has_single_input_argument.rb +156 -0
- data/lib/graphql/schema/input_object.rb +88 -90
- data/lib/graphql/schema/interface.rb +19 -59
- data/lib/graphql/schema/introspection_system.rb +6 -9
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +18 -7
- data/lib/graphql/schema/loader.rb +3 -3
- data/lib/graphql/schema/member/base_dsl_methods.rb +18 -19
- data/lib/graphql/schema/member/build_type.rb +16 -13
- data/lib/graphql/schema/member/has_arguments.rb +288 -84
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +81 -61
- data/lib/graphql/schema/member/has_fields.rb +149 -31
- data/lib/graphql/schema/member/has_interfaces.rb +143 -0
- data/lib/graphql/schema/member/has_validators.rb +32 -6
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/member/validates_input.rb +6 -6
- data/lib/graphql/schema/member.rb +1 -6
- data/lib/graphql/schema/mutation.rb +0 -9
- data/lib/graphql/schema/non_null.rb +7 -7
- data/lib/graphql/schema/object.rb +30 -119
- data/lib/graphql/schema/printer.rb +23 -25
- data/lib/graphql/schema/relay_classic_mutation.rb +13 -90
- data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
- data/lib/graphql/schema/resolver.rb +101 -102
- data/lib/graphql/schema/scalar.rb +20 -21
- data/lib/graphql/schema/subscription.rb +45 -17
- data/lib/graphql/schema/timeout.rb +25 -29
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +21 -4
- data/lib/graphql/schema/union.rb +15 -15
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- 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 +3 -1
- data/lib/graphql/schema/validator/format_validator.rb +4 -5
- data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
- data/lib/graphql/schema/validator/length_validator.rb +5 -3
- data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
- data/lib/graphql/schema/validator/required_validator.rb +29 -15
- data/lib/graphql/schema/validator.rb +35 -27
- data/lib/graphql/schema/warden.rb +259 -132
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +658 -989
- data/lib/graphql/static_validation/all_rules.rb +3 -1
- data/lib/graphql/static_validation/base_visitor.rb +14 -28
- 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 +21 -4
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
- 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 +54 -28
- 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/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 +5 -3
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
- 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 +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +13 -7
- data/lib/graphql/static_validation/validation_context.rb +16 -6
- data/lib/graphql/static_validation/validator.rb +11 -27
- data/lib/graphql/static_validation.rb +0 -3
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +46 -9
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +75 -37
- data/lib/graphql/subscriptions/serialize.rb +25 -3
- data/lib/graphql/subscriptions.rb +59 -47
- data/lib/graphql/testing/helpers.rb +129 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
- data/lib/graphql/tracing/appoptics_trace.rb +251 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
- 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 +183 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +25 -15
- data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +10 -28
- data/lib/graphql/tracing/legacy_trace.rb +69 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +45 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +118 -0
- data/lib/graphql/tracing/platform_tracing.rb +46 -49
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +4 -2
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/sentry_trace.rb +112 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/trace.rb +76 -0
- data/lib/graphql/tracing.rb +20 -41
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +1 -1
- data/lib/graphql/types/iso_8601_date.rb +17 -6
- data/lib/graphql/types/iso_8601_date_time.rb +12 -1
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/base_connection.rb +16 -6
- data/lib/graphql/types/relay/connection_behaviors.rb +82 -32
- data/lib/graphql/types/relay/edge_behaviors.rb +36 -7
- data/lib/graphql/types/relay/has_node_field.rb +2 -2
- data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
- data/lib/graphql/types/relay/node_behaviors.rb +12 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -3
- data/lib/graphql/types/string.rb +2 -2
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/unauthorized_error.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +33 -95
- data/readme.md +13 -6
- metadata +102 -185
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- 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/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- 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 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- 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 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- 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 -240
- 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 -47
- data/lib/graphql/deprecation.rb +0 -13
- 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 -111
- data/lib/graphql/enum_type.rb +0 -129
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- 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 -226
- data/lib/graphql/filter.rb +0 -53
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- 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 -262
- data/lib/graphql/language/parser.y +0 -543
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- 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 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- 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 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- 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 -17
- 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 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/instrumentation.rb +0 -79
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/default_relay.rb +0 -27
- data/lib/graphql/types/relay/node_field.rb +0 -25
- data/lib/graphql/types/relay/nodes_field.rb +0 -27
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- data/lib/graphql/upgrader/schema.rb +0 -38
@@ -3,7 +3,7 @@ module GraphQL
|
|
3
3
|
module StaticValidation
|
4
4
|
# Default rules for {GraphQL::StaticValidation::Validator}
|
5
5
|
#
|
6
|
-
# Order is important here. Some validators
|
6
|
+
# Order is important here. Some validators skip later hooks.
|
7
7
|
# which stops the visit on that node. That way it doesn't try to find fields on types that
|
8
8
|
# don't exist, etc.
|
9
9
|
ALL_RULES = [
|
@@ -33,8 +33,10 @@ module GraphQL
|
|
33
33
|
GraphQL::StaticValidation::VariablesAreUsedAndDefined,
|
34
34
|
GraphQL::StaticValidation::VariableUsagesAreAllowed,
|
35
35
|
GraphQL::StaticValidation::MutationRootExists,
|
36
|
+
GraphQL::StaticValidation::QueryRootExists,
|
36
37
|
GraphQL::StaticValidation::SubscriptionRootExists,
|
37
38
|
GraphQL::StaticValidation::InputObjectNamesAreUnique,
|
39
|
+
GraphQL::StaticValidation::OneOfInputObjectsAreValid,
|
38
40
|
]
|
39
41
|
end
|
40
42
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
module StaticValidation
|
4
|
-
class BaseVisitor < GraphQL::Language::
|
4
|
+
class BaseVisitor < GraphQL::Language::StaticVisitor
|
5
5
|
def initialize(document, context)
|
6
6
|
@path = []
|
7
7
|
@object_types = []
|
@@ -14,11 +14,6 @@ module GraphQL
|
|
14
14
|
super(document)
|
15
15
|
end
|
16
16
|
|
17
|
-
# This will be overwritten by {InternalRepresentation::Rewrite} if it's included
|
18
|
-
def rewrite_document
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
22
17
|
attr_reader :context
|
23
18
|
|
24
19
|
# @return [Array<GraphQL::ObjectType>] Types whose scope we've entered
|
@@ -32,22 +27,13 @@ module GraphQL
|
|
32
27
|
# Build a class to visit the AST and perform validation,
|
33
28
|
# or use a pre-built class if rules is `ALL_RULES` or empty.
|
34
29
|
# @param rules [Array<Module, Class>]
|
35
|
-
# @param rewrite [Boolean] if `false`, don't include rewrite
|
36
30
|
# @return [Class] A class for validating `rules` during visitation
|
37
|
-
def self.including_rules(rules
|
31
|
+
def self.including_rules(rules)
|
38
32
|
if rules.empty?
|
39
|
-
|
40
|
-
|
41
|
-
else
|
42
|
-
# It's not doing _anything?!?_
|
43
|
-
BaseVisitor
|
44
|
-
end
|
33
|
+
# It's not doing _anything?!?_
|
34
|
+
BaseVisitor
|
45
35
|
elsif rules == ALL_RULES
|
46
|
-
|
47
|
-
DefaultVisitor
|
48
|
-
else
|
49
|
-
InterpreterVisitor
|
50
|
-
end
|
36
|
+
InterpreterVisitor
|
51
37
|
else
|
52
38
|
visitor_class = Class.new(self) do
|
53
39
|
include(GraphQL::StaticValidation::DefinitionDependencies)
|
@@ -60,9 +46,6 @@ module GraphQL
|
|
60
46
|
end
|
61
47
|
end
|
62
48
|
|
63
|
-
if rewrite
|
64
|
-
visitor_class.include(GraphQL::InternalRepresentation::Rewrite)
|
65
|
-
end
|
66
49
|
visitor_class.include(ContextMethods)
|
67
50
|
visitor_class
|
68
51
|
end
|
@@ -94,7 +77,7 @@ module GraphQL
|
|
94
77
|
|
95
78
|
def on_field(node, parent)
|
96
79
|
parent_type = @object_types.last
|
97
|
-
field_definition = @schema.get_field(parent_type, node.name)
|
80
|
+
field_definition = @schema.get_field(parent_type, node.name, @context.query.context)
|
98
81
|
@field_definitions.push(field_definition)
|
99
82
|
if !field_definition.nil?
|
100
83
|
next_object_type = field_definition.type.unwrap
|
@@ -110,7 +93,7 @@ module GraphQL
|
|
110
93
|
end
|
111
94
|
|
112
95
|
def on_directive(node, parent)
|
113
|
-
directive_defn = @
|
96
|
+
directive_defn = @context.schema_directives[node.name]
|
114
97
|
@directive_definitions.push(directive_defn)
|
115
98
|
super
|
116
99
|
@directive_definitions.pop
|
@@ -120,14 +103,14 @@ module GraphQL
|
|
120
103
|
argument_defn = if (arg = @argument_definitions.last)
|
121
104
|
arg_type = arg.type.unwrap
|
122
105
|
if arg_type.kind.input_object?
|
123
|
-
arg_type
|
106
|
+
@context.warden.get_argument(arg_type, node.name)
|
124
107
|
else
|
125
108
|
nil
|
126
109
|
end
|
127
110
|
elsif (directive_defn = @directive_definitions.last)
|
128
|
-
directive_defn
|
111
|
+
@context.warden.get_argument(directive_defn, node.name)
|
129
112
|
elsif (field_defn = @field_definitions.last)
|
130
|
-
field_defn
|
113
|
+
@context.warden.get_argument(field_defn, node.name)
|
131
114
|
else
|
132
115
|
nil
|
133
116
|
end
|
@@ -187,7 +170,7 @@ module GraphQL
|
|
187
170
|
|
188
171
|
def on_fragment_with_type(node)
|
189
172
|
object_type = if node.type
|
190
|
-
@
|
173
|
+
@context.warden.get_type(node.type.name)
|
191
174
|
else
|
192
175
|
@object_types.last
|
193
176
|
end
|
@@ -205,6 +188,9 @@ module GraphQL
|
|
205
188
|
private
|
206
189
|
|
207
190
|
def add_error(error, path: nil)
|
191
|
+
if @context.too_many_errors?
|
192
|
+
throw :too_many_validation_errors
|
193
|
+
end
|
208
194
|
error.path ||= (path || @path.dup)
|
209
195
|
context.errors << error
|
210
196
|
end
|
@@ -70,7 +70,6 @@ module GraphQL
|
|
70
70
|
@dependency_map ||= resolve_dependencies(&block)
|
71
71
|
end
|
72
72
|
|
73
|
-
|
74
73
|
# Map definition AST nodes to the definition AST nodes they depend on.
|
75
74
|
# Expose circular dependencies.
|
76
75
|
class DependencyMap
|
@@ -128,8 +127,14 @@ module GraphQL
|
|
128
127
|
# same name as if they were the same name. If _any_ of the fragments
|
129
128
|
# with that name has a dependency, we record it.
|
130
129
|
independent_fragment_nodes = @defdep_fragment_definitions.values.flatten - @defdep_immediate_dependencies.keys
|
131
|
-
|
130
|
+
visited_fragment_names = Set.new
|
132
131
|
while fragment_node = independent_fragment_nodes.pop
|
132
|
+
if visited_fragment_names.add?(fragment_node.name)
|
133
|
+
# this is a new fragment name
|
134
|
+
else
|
135
|
+
# this is a duplicate fragment name
|
136
|
+
next
|
137
|
+
end
|
133
138
|
loops += 1
|
134
139
|
if loops > max_loops
|
135
140
|
raise("Resolution loops exceeded the number of definitions; infinite loop detected. (Max: #{max_loops}, Current: #{loops})")
|
@@ -30,10 +30,12 @@ module GraphQL
|
|
30
30
|
}.tap { |h| h["path"] = path unless path.nil? }
|
31
31
|
end
|
32
32
|
|
33
|
+
attr_reader :nodes
|
34
|
+
|
33
35
|
private
|
34
36
|
|
35
37
|
def locations
|
36
|
-
|
38
|
+
nodes.map do |node|
|
37
39
|
h = {"line" => node.line, "column" => node.col}
|
38
40
|
h["filename"] = node.filename if node.filename
|
39
41
|
h
|
@@ -18,6 +18,19 @@ module GraphQL
|
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
+
def replace_nulls_in(ast_value)
|
22
|
+
case ast_value
|
23
|
+
when Array
|
24
|
+
ast_value.map { |v| replace_nulls_in(v) }
|
25
|
+
when GraphQL::Language::Nodes::InputObject
|
26
|
+
ast_value.to_h
|
27
|
+
when GraphQL::Language::Nodes::NullValue
|
28
|
+
nil
|
29
|
+
else
|
30
|
+
ast_value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
21
34
|
def recursively_validate(ast_value, type)
|
22
35
|
if type.nil?
|
23
36
|
# this means we're an undefined argument, see #present_input_field_values_are_valid
|
@@ -42,7 +55,8 @@ module GraphQL
|
|
42
55
|
@valid_response
|
43
56
|
elsif type.kind.scalar? && constant_scalar?(ast_value)
|
44
57
|
maybe_raise_if_invalid(ast_value) do
|
45
|
-
|
58
|
+
ruby_value = replace_nulls_in(ast_value)
|
59
|
+
type.validate_input(ruby_value, @context)
|
46
60
|
end
|
47
61
|
elsif type.kind.enum?
|
48
62
|
maybe_raise_if_invalid(ast_value) do
|
@@ -95,9 +109,9 @@ module GraphQL
|
|
95
109
|
def required_input_fields_are_present(type, ast_node)
|
96
110
|
# TODO - would be nice to use these to create an error message so the caller knows
|
97
111
|
# that required fields are missing
|
98
|
-
required_field_names =
|
99
|
-
.select { |argument| argument.type.kind.non_null? &&
|
100
|
-
.map(&:name)
|
112
|
+
required_field_names = @warden.arguments(type)
|
113
|
+
.select { |argument| argument.type.kind.non_null? && !argument.default_value? }
|
114
|
+
.map!(&:name)
|
101
115
|
|
102
116
|
present_field_names = ast_node.arguments.map(&:name)
|
103
117
|
missing_required_field_names = required_field_names - present_field_names
|
@@ -108,6 +122,9 @@ module GraphQL
|
|
108
122
|
arg_type = @warden.get_argument(type, name).type
|
109
123
|
recursively_validate(GraphQL::Language::Nodes::NullValue.new(name: name), arg_type)
|
110
124
|
end
|
125
|
+
if type.one_of? && ast_node.arguments.size != 1
|
126
|
+
results << Query::InputValidationResult.from_problem("`#{type.graphql_name}` is a OneOf type, so only one argument may be given (instead of #{ast_node.arguments.size})")
|
127
|
+
end
|
111
128
|
merge_results(results)
|
112
129
|
end
|
113
130
|
end
|
@@ -15,7 +15,7 @@ module GraphQL
|
|
15
15
|
if @context.schema.error_bubbling || context.errors.none? { |err| err.path.take(@path.size) == @path }
|
16
16
|
parent_defn = parent_definition(parent)
|
17
17
|
|
18
|
-
if parent_defn && (arg_defn = parent_defn
|
18
|
+
if parent_defn && (arg_defn = context.warden.get_argument(parent_defn, node.name))
|
19
19
|
validation_result = context.validate_literal(node.value, arg_defn.type)
|
20
20
|
if !validation_result.valid?
|
21
21
|
kind_of_node = node_type(parent)
|
@@ -9,11 +9,17 @@ module GraphQL
|
|
9
9
|
|
10
10
|
def on_directive(node, parent)
|
11
11
|
if !@directive_names.include?(node.name)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
@directives_are_defined_errors_by_name ||= {}
|
13
|
+
error = @directives_are_defined_errors_by_name[node.name] ||= begin
|
14
|
+
err = GraphQL::StaticValidation::DirectivesAreDefinedError.new(
|
15
|
+
"Directive @#{node.name} is not defined",
|
16
|
+
nodes: [],
|
17
|
+
directive: node.name
|
18
|
+
)
|
19
|
+
add_error(err)
|
20
|
+
err
|
21
|
+
end
|
22
|
+
error.nodes << node
|
17
23
|
else
|
18
24
|
super
|
19
25
|
end
|
@@ -5,27 +5,27 @@ module GraphQL
|
|
5
5
|
include GraphQL::Language
|
6
6
|
|
7
7
|
def on_directive(node, parent)
|
8
|
-
validate_location(node, parent, context.
|
8
|
+
validate_location(node, parent, context.schema_directives)
|
9
9
|
super
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
14
|
LOCATION_MESSAGE_NAMES = {
|
15
|
-
GraphQL::Directive::QUERY => "queries",
|
16
|
-
GraphQL::Directive::MUTATION => "mutations",
|
17
|
-
GraphQL::Directive::SUBSCRIPTION => "subscriptions",
|
18
|
-
GraphQL::Directive::FIELD => "fields",
|
19
|
-
GraphQL::Directive::FRAGMENT_DEFINITION => "fragment definitions",
|
20
|
-
GraphQL::Directive::FRAGMENT_SPREAD => "fragment spreads",
|
21
|
-
GraphQL::Directive::INLINE_FRAGMENT => "inline fragments",
|
15
|
+
GraphQL::Schema::Directive::QUERY => "queries",
|
16
|
+
GraphQL::Schema::Directive::MUTATION => "mutations",
|
17
|
+
GraphQL::Schema::Directive::SUBSCRIPTION => "subscriptions",
|
18
|
+
GraphQL::Schema::Directive::FIELD => "fields",
|
19
|
+
GraphQL::Schema::Directive::FRAGMENT_DEFINITION => "fragment definitions",
|
20
|
+
GraphQL::Schema::Directive::FRAGMENT_SPREAD => "fragment spreads",
|
21
|
+
GraphQL::Schema::Directive::INLINE_FRAGMENT => "inline fragments",
|
22
22
|
}
|
23
23
|
|
24
24
|
SIMPLE_LOCATIONS = {
|
25
|
-
Nodes::Field => GraphQL::Directive::FIELD,
|
26
|
-
Nodes::InlineFragment => GraphQL::Directive::INLINE_FRAGMENT,
|
27
|
-
Nodes::FragmentSpread => GraphQL::Directive::FRAGMENT_SPREAD,
|
28
|
-
Nodes::FragmentDefinition => GraphQL::Directive::FRAGMENT_DEFINITION,
|
25
|
+
Nodes::Field => GraphQL::Schema::Directive::FIELD,
|
26
|
+
Nodes::InlineFragment => GraphQL::Schema::Directive::INLINE_FRAGMENT,
|
27
|
+
Nodes::FragmentSpread => GraphQL::Schema::Directive::FRAGMENT_SPREAD,
|
28
|
+
Nodes::FragmentDefinition => GraphQL::Schema::Directive::FRAGMENT_DEFINITION,
|
29
29
|
}
|
30
30
|
|
31
31
|
SIMPLE_LOCATION_NODES = SIMPLE_LOCATIONS.keys
|
@@ -34,7 +34,7 @@ module GraphQL
|
|
34
34
|
directive_defn = directives[ast_directive.name]
|
35
35
|
case ast_parent
|
36
36
|
when Nodes::OperationDefinition
|
37
|
-
required_location = GraphQL::Directive.const_get(ast_parent.operation_type.upcase)
|
37
|
+
required_location = GraphQL::Schema::Directive.const_get(ast_parent.operation_type.upcase)
|
38
38
|
assert_includes_location(directive_defn, ast_directive, required_location)
|
39
39
|
when *SIMPLE_LOCATION_NODES
|
40
40
|
required_location = SIMPLE_LOCATIONS[ast_parent.class]
|
@@ -26,11 +26,19 @@ module GraphQL
|
|
26
26
|
msg = if resolved_type.nil?
|
27
27
|
nil
|
28
28
|
elsif resolved_type.kind.scalar? && ast_node.selections.any?
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
selection_strs = ast_node.selections.map do |n|
|
30
|
+
case n
|
31
|
+
when GraphQL::Language::Nodes::InlineFragment
|
32
|
+
"\"... on #{n.type.name} { ... }\""
|
33
|
+
when GraphQL::Language::Nodes::Field
|
34
|
+
"\"#{n.name}\""
|
35
|
+
when GraphQL::Language::Nodes::FragmentSpread
|
36
|
+
"\"#{n.name}\""
|
37
|
+
else
|
38
|
+
raise "Invariant: unexpected selection node: #{n}"
|
39
|
+
end
|
33
40
|
end
|
41
|
+
"Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{selection_strs.join(", ")}])"
|
34
42
|
elsif resolved_type.kind.fields? && ast_node.selections.empty?
|
35
43
|
"Field must have selections (%{node_name} returns #{resolved_type.graphql_name} but has no selections. Did you mean '#{ast_node.name} { ... }'?)"
|
36
44
|
else
|
@@ -9,7 +9,8 @@ module GraphQL
|
|
9
9
|
# without ambiguity.
|
10
10
|
#
|
11
11
|
# Original Algorithm: https://github.com/graphql/graphql-js/blob/master/src/validation/rules/OverlappingFieldsCanBeMerged.js
|
12
|
-
NO_ARGS =
|
12
|
+
NO_ARGS = GraphQL::EmptyObjects::EMPTY_HASH
|
13
|
+
|
13
14
|
Field = Struct.new(:node, :definition, :owner_type, :parents)
|
14
15
|
FragmentSpread = Struct.new(:name, :parents)
|
15
16
|
|
@@ -17,24 +18,47 @@ module GraphQL
|
|
17
18
|
super
|
18
19
|
@visited_fragments = {}
|
19
20
|
@compared_fragments = {}
|
21
|
+
@conflict_count = 0
|
20
22
|
end
|
21
23
|
|
22
24
|
def on_operation_definition(node, _parent)
|
23
|
-
conflicts_within_selection_set(node, type_definition)
|
25
|
+
setting_errors { conflicts_within_selection_set(node, type_definition) }
|
24
26
|
super
|
25
27
|
end
|
26
28
|
|
27
29
|
def on_field(node, _parent)
|
28
|
-
conflicts_within_selection_set(node, type_definition)
|
30
|
+
setting_errors { conflicts_within_selection_set(node, type_definition) }
|
29
31
|
super
|
30
32
|
end
|
31
33
|
|
32
34
|
private
|
33
35
|
|
36
|
+
def field_conflicts
|
37
|
+
@field_conflicts ||= Hash.new do |errors, field|
|
38
|
+
errors[field] = GraphQL::StaticValidation::FieldsWillMergeError.new(kind: :field, field_name: field)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def arg_conflicts
|
43
|
+
@arg_conflicts ||= Hash.new do |errors, field|
|
44
|
+
errors[field] = GraphQL::StaticValidation::FieldsWillMergeError.new(kind: :argument, field_name: field)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def setting_errors
|
49
|
+
@field_conflicts = nil
|
50
|
+
@arg_conflicts = nil
|
51
|
+
|
52
|
+
yield
|
53
|
+
# don't initialize these if they weren't initialized in the block:
|
54
|
+
@field_conflicts && @field_conflicts.each_value { |error| add_error(error) }
|
55
|
+
@arg_conflicts && @arg_conflicts.each_value { |error| add_error(error) }
|
56
|
+
end
|
57
|
+
|
34
58
|
def conflicts_within_selection_set(node, parent_type)
|
35
59
|
return if parent_type.nil?
|
36
60
|
|
37
|
-
fields, fragment_spreads = fields_and_fragments_from_selection(node, owner_type: parent_type, parents:
|
61
|
+
fields, fragment_spreads = fields_and_fragments_from_selection(node, owner_type: parent_type, parents: nil)
|
38
62
|
|
39
63
|
# (A) Find find all conflicts "within" the fields of this selection set.
|
40
64
|
find_conflicts_within(fields)
|
@@ -174,15 +198,21 @@ module GraphQL
|
|
174
198
|
response_keys.each do |key, fields|
|
175
199
|
next if fields.size < 2
|
176
200
|
# find conflicts within nodes
|
177
|
-
|
178
|
-
|
201
|
+
i = 0
|
202
|
+
while i < fields.size
|
203
|
+
j = i + 1
|
204
|
+
while j < fields.size
|
179
205
|
find_conflict(key, fields[i], fields[j])
|
206
|
+
j += 1
|
180
207
|
end
|
208
|
+
i += 1
|
181
209
|
end
|
182
210
|
end
|
183
211
|
end
|
184
212
|
|
185
213
|
def find_conflict(response_key, field1, field2, mutually_exclusive: false)
|
214
|
+
return if @conflict_count >= context.max_errors
|
215
|
+
|
186
216
|
node1 = field1.node
|
187
217
|
node2 = field2.node
|
188
218
|
|
@@ -191,28 +221,21 @@ module GraphQL
|
|
191
221
|
|
192
222
|
if !are_mutually_exclusive
|
193
223
|
if node1.name != node2.name
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
field_name: response_key,
|
201
|
-
conflicts: errored_nodes
|
202
|
-
)
|
224
|
+
conflict = field_conflicts[response_key]
|
225
|
+
|
226
|
+
conflict.add_conflict(node1, node1.name)
|
227
|
+
conflict.add_conflict(node2, node2.name)
|
228
|
+
|
229
|
+
@conflict_count += 1
|
203
230
|
end
|
204
231
|
|
205
232
|
if !same_arguments?(node1, node2)
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
path: [],
|
213
|
-
field_name: response_key,
|
214
|
-
conflicts: conflicts
|
215
|
-
)
|
233
|
+
conflict = arg_conflicts[response_key]
|
234
|
+
|
235
|
+
conflict.add_conflict(node1, GraphQL::Language.serialize(serialize_field_args(node1)))
|
236
|
+
conflict.add_conflict(node2, GraphQL::Language.serialize(serialize_field_args(node2)))
|
237
|
+
|
238
|
+
@conflict_count += 1
|
216
239
|
end
|
217
240
|
end
|
218
241
|
|
@@ -224,7 +247,9 @@ module GraphQL
|
|
224
247
|
end
|
225
248
|
|
226
249
|
def find_conflicts_between_sub_selection_sets(field1, field2, mutually_exclusive:)
|
227
|
-
return if field1.definition.nil? ||
|
250
|
+
return if field1.definition.nil? ||
|
251
|
+
field2.definition.nil? ||
|
252
|
+
(field1.node.selections.empty? && field2.node.selections.empty?)
|
228
253
|
|
229
254
|
return_type1 = field1.definition.type.unwrap
|
230
255
|
return_type2 = field2.definition.type.unwrap
|
@@ -298,12 +323,13 @@ module GraphQL
|
|
298
323
|
end
|
299
324
|
end
|
300
325
|
|
301
|
-
NO_SELECTIONS = [
|
326
|
+
NO_SELECTIONS = [GraphQL::EmptyObjects::EMPTY_HASH, GraphQL::EmptyObjects::EMPTY_ARRAY].freeze
|
302
327
|
|
303
328
|
def fields_and_fragments_from_selection(node, owner_type:, parents:)
|
304
329
|
if node.selections.empty?
|
305
330
|
NO_SELECTIONS
|
306
331
|
else
|
332
|
+
parents ||= []
|
307
333
|
fields, fragment_spreads = find_fields_and_fragments(node.selections, owner_type: owner_type, parents: parents, fields: [], fragment_spreads: [])
|
308
334
|
response_keys = fields.group_by { |f| f.node.alias || f.node.name }
|
309
335
|
[response_keys, fragment_spreads]
|
@@ -314,7 +340,7 @@ module GraphQL
|
|
314
340
|
selections.each do |node|
|
315
341
|
case node
|
316
342
|
when GraphQL::Language::Nodes::Field
|
317
|
-
definition = context.
|
343
|
+
definition = context.warden.get_field(owner_type, node.name)
|
318
344
|
fields << Field.new(node, definition, owner_type, parents)
|
319
345
|
when GraphQL::Language::Nodes::InlineFragment
|
320
346
|
fragment_type = node.type ? context.warden.get_type(node.type.name) : owner_type
|
@@ -3,12 +3,33 @@ module GraphQL
|
|
3
3
|
module StaticValidation
|
4
4
|
class FieldsWillMergeError < StaticValidation::Error
|
5
5
|
attr_reader :field_name
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :kind
|
7
|
+
|
8
|
+
def initialize(kind:, field_name:)
|
9
|
+
super(nil)
|
7
10
|
|
8
|
-
def initialize(message, path: nil, nodes: [], field_name:, conflicts:)
|
9
|
-
super(message, path: path, nodes: nodes)
|
10
11
|
@field_name = field_name
|
11
|
-
@
|
12
|
+
@kind = kind
|
13
|
+
@conflicts = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
"Field '#{field_name}' has #{kind == :argument ? 'an' : 'a'} #{kind} conflict: #{conflicts}?"
|
18
|
+
end
|
19
|
+
|
20
|
+
def path
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
def conflicts
|
25
|
+
@conflicts.join(' or ')
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_conflict(node, conflict_str)
|
29
|
+
return if nodes.include?(node)
|
30
|
+
|
31
|
+
@nodes << node
|
32
|
+
@conflicts << conflict_str
|
12
33
|
end
|
13
34
|
|
14
35
|
# A hash representation of this Message
|
@@ -7,12 +7,12 @@ module GraphQL
|
|
7
7
|
dependency_map = context.dependencies
|
8
8
|
dependency_map.cyclical_definitions.each do |defn|
|
9
9
|
if defn.node.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
|
10
|
-
|
10
|
+
add_error(GraphQL::StaticValidation::FragmentsAreFiniteError.new(
|
11
11
|
"Fragment #{defn.name} contains an infinite loop",
|
12
12
|
nodes: defn.node,
|
13
13
|
path: defn.path,
|
14
14
|
name: defn.name
|
15
|
-
)
|
15
|
+
))
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module StaticValidation
|
4
|
+
module OneOfInputObjectsAreValid
|
5
|
+
def on_input_object(node, parent)
|
6
|
+
return super unless parent.is_a?(GraphQL::Language::Nodes::Argument)
|
7
|
+
|
8
|
+
parent_type = get_parent_type(context, parent)
|
9
|
+
return super unless parent_type && parent_type.kind.input_object? && parent_type.one_of?
|
10
|
+
|
11
|
+
validate_one_of_input_object(node, context, parent_type)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def validate_one_of_input_object(ast_node, context, parent_type)
|
18
|
+
present_fields = ast_node.arguments.map(&:name)
|
19
|
+
input_object_type = parent_type.to_type_signature
|
20
|
+
|
21
|
+
if present_fields.count != 1
|
22
|
+
add_error(
|
23
|
+
OneOfInputObjectsAreValidError.new(
|
24
|
+
"OneOf Input Object '#{input_object_type}' must specify exactly one key.",
|
25
|
+
path: context.path,
|
26
|
+
nodes: ast_node,
|
27
|
+
input_object_type: input_object_type
|
28
|
+
)
|
29
|
+
)
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
field = present_fields.first
|
34
|
+
value = ast_node.arguments.first.value
|
35
|
+
|
36
|
+
if value.is_a?(GraphQL::Language::Nodes::NullValue)
|
37
|
+
add_error(
|
38
|
+
OneOfInputObjectsAreValidError.new(
|
39
|
+
"Argument '#{input_object_type}.#{field}' must be non-null.",
|
40
|
+
path: [*context.path, field],
|
41
|
+
nodes: ast_node.arguments.first,
|
42
|
+
input_object_type: input_object_type
|
43
|
+
)
|
44
|
+
)
|
45
|
+
return
|
46
|
+
end
|
47
|
+
|
48
|
+
if value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
|
49
|
+
variable_name = value.name
|
50
|
+
variable_type = @declared_variables[variable_name].type
|
51
|
+
|
52
|
+
unless variable_type.is_a?(GraphQL::Language::Nodes::NonNullType)
|
53
|
+
add_error(
|
54
|
+
OneOfInputObjectsAreValidError.new(
|
55
|
+
"Variable '#{variable_name}' must be non-nullable to be used for OneOf Input Object '#{input_object_type}'.",
|
56
|
+
path: [*context.path, field],
|
57
|
+
nodes: ast_node,
|
58
|
+
input_object_type: input_object_type
|
59
|
+
)
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module StaticValidation
|
4
|
+
class OneOfInputObjectsAreValidError < StaticValidation::Error
|
5
|
+
attr_reader :input_object_type
|
6
|
+
|
7
|
+
def initialize(message, path:, nodes:, input_object_type:)
|
8
|
+
super(message, path: path, nodes: nodes)
|
9
|
+
@input_object_type = input_object_type
|
10
|
+
end
|
11
|
+
|
12
|
+
# A hash representation of this Message
|
13
|
+
def to_h
|
14
|
+
extensions = {
|
15
|
+
"code" => code,
|
16
|
+
"inputObjectType" => input_object_type
|
17
|
+
}
|
18
|
+
|
19
|
+
super.merge({
|
20
|
+
"extensions" => extensions
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
def code
|
25
|
+
"invalidOneOfInputObject"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module StaticValidation
|
4
|
+
module QueryRootExists
|
5
|
+
def on_operation_definition(node, _parent)
|
6
|
+
if (node.operation_type == 'query' || node.operation_type.nil?) && context.warden.root_type_for_operation("query").nil?
|
7
|
+
add_error(GraphQL::StaticValidation::QueryRootExistsError.new(
|
8
|
+
'Schema is not configured for queries',
|
9
|
+
nodes: node
|
10
|
+
))
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|