graphql 0.16.0 → 2.0.15
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 +5 -5
- data/.yardopts +5 -0
- data/lib/generators/graphql/core.rb +69 -0
- data/lib/generators/graphql/enum_generator.rb +27 -0
- 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/install/templates/base_mutation.erb +10 -0
- data/lib/generators/graphql/install/templates/mutation_type.erb +12 -0
- data/lib/generators/graphql/install_generator.rb +197 -0
- data/lib/generators/graphql/interface_generator.rb +27 -0
- data/lib/generators/graphql/loader_generator.rb +21 -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 +30 -0
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +50 -0
- 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 +22 -0
- data/lib/generators/graphql/templates/base_argument.erb +6 -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 +6 -0
- data/lib/generators/graphql/templates/base_field.erb +7 -0
- data/lib/generators/graphql/templates/base_input_object.erb +7 -0
- data/lib/generators/graphql/templates/base_interface.erb +9 -0
- data/lib/generators/graphql/templates/base_object.erb +7 -0
- data/lib/generators/graphql/templates/base_scalar.erb +6 -0
- data/lib/generators/graphql/templates/base_union.erb +6 -0
- data/lib/generators/graphql/templates/enum.erb +11 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +52 -0
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +10 -0
- data/lib/generators/graphql/templates/loader.erb +19 -0
- data/lib/generators/graphql/templates/mutation.erb +16 -0
- 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 +10 -0
- data/lib/generators/graphql/templates/query_type.erb +15 -0
- data/lib/generators/graphql/templates/scalar.erb +17 -0
- data/lib/generators/graphql/templates/schema.erb +30 -0
- data/lib/generators/graphql/templates/union.erb +9 -0
- data/lib/generators/graphql/type_generator.rb +135 -0
- data/lib/generators/graphql/union_generator.rb +33 -0
- data/lib/graphql/analysis/ast/analyzer.rb +84 -0
- data/lib/graphql/analysis/ast/field_usage.rb +57 -0
- data/lib/graphql/analysis/ast/max_query_complexity.rb +22 -0
- data/lib/graphql/analysis/ast/max_query_depth.rb +22 -0
- data/lib/graphql/analysis/ast/query_complexity.rb +230 -0
- data/lib/graphql/analysis/ast/query_depth.rb +55 -0
- data/lib/graphql/analysis/ast/visitor.rb +269 -0
- data/lib/graphql/analysis/ast.rb +81 -0
- data/lib/graphql/analysis.rb +2 -5
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/backtrace/inspect_result.rb +50 -0
- data/lib/graphql/backtrace/table.rb +141 -0
- data/lib/graphql/backtrace/traced_error.rb +54 -0
- data/lib/graphql/backtrace/tracer.rb +80 -0
- data/lib/graphql/backtrace.rb +58 -0
- data/lib/graphql/coercion_error.rb +13 -0
- 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 +19 -0
- data/lib/graphql/execution/directive_checks.rb +37 -0
- data/lib/graphql/execution/errors.rb +93 -0
- 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 +105 -0
- data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +77 -0
- data/lib/graphql/execution/interpreter/runtime.rb +994 -0
- data/lib/graphql/execution/interpreter.rb +226 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +98 -0
- data/lib/graphql/execution/lazy.rb +75 -0
- data/lib/graphql/execution/lookahead.rb +311 -0
- data/lib/graphql/execution/multiplex.rb +45 -0
- data/lib/graphql/execution.rb +18 -0
- data/lib/graphql/execution_error.rb +34 -1
- data/lib/graphql/filter.rb +53 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +36 -0
- data/lib/graphql/introspection/base_object.rb +13 -0
- data/lib/graphql/introspection/directive_location_enum.rb +12 -5
- data/lib/graphql/introspection/directive_type.rb +30 -10
- data/lib/graphql/introspection/dynamic_fields.rb +12 -0
- data/lib/graphql/introspection/entry_points.rb +22 -0
- data/lib/graphql/introspection/enum_value_type.rb +21 -8
- data/lib/graphql/introspection/field_type.rb +26 -10
- data/lib/graphql/introspection/input_value_type.rb +64 -14
- data/lib/graphql/introspection/introspection_query.rb +7 -76
- data/lib/graphql/introspection/schema_type.rb +42 -17
- data/lib/graphql/introspection/type_kind_enum.rb +11 -5
- data/lib/graphql/introspection/type_type.rb +104 -16
- data/lib/graphql/introspection.rb +104 -13
- data/lib/graphql/invalid_name_error.rb +11 -0
- data/lib/graphql/invalid_null_error.rb +36 -8
- data/lib/graphql/language/block_string.rb +99 -0
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +41 -0
- data/lib/graphql/language/document_from_schema_definition.rb +335 -0
- data/lib/graphql/language/generation.rb +16 -86
- data/lib/graphql/language/lexer.rb +1436 -705
- data/lib/graphql/language/lexer.rl +172 -64
- data/lib/graphql/language/nodes.rb +617 -105
- data/lib/graphql/language/parser.rb +1524 -430
- data/lib/graphql/language/parser.y +348 -73
- data/lib/graphql/language/printer.rb +386 -0
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +16 -3
- data/lib/graphql/language/visitor.rb +169 -25
- data/lib/graphql/language.rb +30 -0
- data/lib/graphql/load_application_object_failed_error.rb +22 -0
- data/lib/graphql/name_validator.rb +11 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +85 -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 +24 -0
- data/lib/graphql/query/context.rb +266 -12
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +34 -7
- data/lib/graphql/query/null_context.rb +52 -0
- data/lib/graphql/query/result.rb +63 -0
- data/lib/graphql/query/validation_pipeline.rb +114 -0
- data/lib/graphql/query/variable_validation_error.rb +27 -3
- data/lib/graphql/query/variables.rb +75 -24
- data/lib/graphql/query.rb +359 -92
- data/lib/graphql/railtie.rb +13 -0
- data/lib/graphql/rake_task/validate.rb +63 -0
- data/lib/graphql/rake_task.rb +146 -0
- data/lib/graphql/relay/range_add.rb +52 -0
- data/lib/graphql/relay.rb +3 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/runtime_type_error.rb +5 -0
- data/lib/graphql/schema/addition.rb +245 -0
- data/lib/graphql/schema/argument.rb +395 -0
- data/lib/graphql/schema/base_64_bp.rb +26 -0
- data/lib/graphql/schema/base_64_encoder.rb +21 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +47 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +78 -0
- data/lib/graphql/schema/build_from_definition.rb +492 -0
- data/lib/graphql/schema/built_in_types.rb +12 -0
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/feature.rb +66 -0
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +25 -0
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +25 -0
- data/lib/graphql/schema/directive/transform.rb +60 -0
- data/lib/graphql/schema/directive.rb +212 -0
- data/lib/graphql/schema/enum.rb +176 -0
- data/lib/graphql/schema/enum_value.rb +77 -0
- data/lib/graphql/schema/field/connection_extension.rb +80 -0
- data/lib/graphql/schema/field/scope_extension.rb +22 -0
- data/lib/graphql/schema/field.rb +862 -0
- data/lib/graphql/schema/field_extension.rb +156 -0
- data/lib/graphql/schema/find_inherited_value.rb +36 -0
- data/lib/graphql/schema/finder.rb +155 -0
- data/lib/graphql/schema/input_object.rb +258 -0
- data/lib/graphql/schema/interface.rb +113 -0
- data/lib/graphql/schema/introspection_system.rb +164 -0
- data/lib/graphql/schema/invalid_type_error.rb +1 -0
- data/lib/graphql/schema/late_bound_type.rb +37 -0
- data/lib/graphql/schema/list.rb +86 -0
- data/lib/graphql/schema/loader.rb +228 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +124 -0
- data/lib/graphql/schema/member/build_type.rb +178 -0
- data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
- data/lib/graphql/schema/member/has_arguments.rb +376 -0
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +113 -0
- data/lib/graphql/schema/member/has_fields.rb +163 -0
- data/lib/graphql/schema/member/has_interfaces.rb +88 -0
- data/lib/graphql/schema/member/has_path.rb +25 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +73 -0
- data/lib/graphql/schema/member/scoped.rb +21 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +38 -0
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +39 -0
- data/lib/graphql/schema/mutation.rb +85 -0
- data/lib/graphql/schema/non_null.rb +67 -0
- data/lib/graphql/schema/null_mask.rb +11 -0
- data/lib/graphql/schema/object.rb +117 -0
- data/lib/graphql/schema/printer.rb +72 -128
- data/lib/graphql/schema/relay_classic_mutation.rb +179 -0
- data/lib/graphql/schema/resolver/has_payload_type.rb +106 -0
- data/lib/graphql/schema/resolver.rb +402 -0
- data/lib/graphql/schema/scalar.rb +68 -0
- data/lib/graphql/schema/subscription.rb +148 -0
- data/lib/graphql/schema/timeout.rb +123 -0
- data/lib/graphql/schema/type_expression.rb +29 -5
- data/lib/graphql/schema/type_membership.rb +51 -0
- data/lib/graphql/schema/union.rb +81 -0
- data/lib/graphql/schema/unique_within_type.rb +34 -0
- 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 +413 -0
- data/lib/graphql/schema/wrapper.rb +24 -0
- data/lib/graphql/schema.rb +1179 -104
- data/lib/graphql/static_validation/all_rules.rb +14 -0
- data/lib/graphql/static_validation/base_visitor.rb +200 -0
- data/lib/graphql/static_validation/definition_dependencies.rb +198 -0
- data/lib/graphql/static_validation/error.rb +46 -0
- data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
- data/lib/graphql/static_validation/literal_validator.rb +113 -22
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +59 -11
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +48 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +31 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +62 -8
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +37 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +20 -13
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +32 -26
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +21 -23
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +55 -18
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +390 -70
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +53 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +54 -37
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +26 -16
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +13 -19
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +16 -0
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +22 -33
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
- 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/mutation_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +41 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -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/operation_names_are_valid.rb +36 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -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 +22 -21
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +59 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +56 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +36 -18
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +24 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +103 -39
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +22 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +92 -70
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
- data/lib/graphql/static_validation/type_stack.rb +85 -24
- data/lib/graphql/static_validation/validation_context.rb +25 -46
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +46 -15
- data/lib/graphql/static_validation.rb +6 -3
- data/lib/graphql/string_encoding_error.rb +20 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +247 -0
- 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 +144 -0
- data/lib/graphql/subscriptions/instrumentation.rb +28 -0
- data/lib/graphql/subscriptions/serialize.rb +158 -0
- data/lib/graphql/subscriptions.rb +306 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +21 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +51 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +100 -0
- data/lib/graphql/tracing/instrumentation_tracing.rb +83 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +51 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +122 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +32 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +67 -0
- data/lib/graphql/tracing/scout_tracing.rb +54 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +94 -0
- data/lib/graphql/type_kinds.rb +50 -22
- data/lib/graphql/types/big_int.rb +23 -0
- data/lib/graphql/types/boolean.rb +18 -0
- data/lib/graphql/types/float.rb +19 -0
- data/lib/graphql/types/id.rb +24 -0
- data/lib/graphql/types/int.rb +36 -0
- data/lib/graphql/types/iso_8601_date.rb +45 -0
- data/lib/graphql/types/iso_8601_date_time.rb +76 -0
- data/lib/graphql/types/json.rb +25 -0
- data/lib/graphql/types/relay/base_connection.rb +49 -0
- data/lib/graphql/types/relay/base_edge.rb +29 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +154 -0
- data/lib/graphql/types/relay/default_relay.rb +21 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +64 -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 +15 -0
- data/lib/graphql/types/relay/node_behaviors.rb +19 -0
- data/lib/graphql/types/relay/page_info.rb +11 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +39 -0
- data/lib/graphql/types/string.rb +29 -0
- data/lib/graphql/types.rb +11 -0
- data/lib/graphql/unauthorized_error.rb +29 -0
- data/lib/graphql/unauthorized_field_error.rb +23 -0
- data/lib/graphql/unresolved_type_error.rb +35 -0
- data/lib/graphql/version.rb +2 -1
- data/lib/graphql.rb +86 -41
- data/readme.md +15 -101
- metadata +394 -279
- data/lib/graphql/analysis/analyze_query.rb +0 -73
- data/lib/graphql/analysis/max_query_complexity.rb +0 -25
- data/lib/graphql/analysis/max_query_depth.rb +0 -25
- data/lib/graphql/analysis/query_complexity.rb +0 -122
- data/lib/graphql/analysis/query_depth.rb +0 -54
- data/lib/graphql/argument.rb +0 -25
- data/lib/graphql/base_type.rb +0 -115
- data/lib/graphql/boolean_type.rb +0 -9
- data/lib/graphql/define/assign_argument.rb +0 -20
- data/lib/graphql/define/assign_enum_value.rb +0 -16
- data/lib/graphql/define/assign_object_field.rb +0 -21
- data/lib/graphql/define/assignment_dictionary.rb +0 -26
- data/lib/graphql/define/defined_object_proxy.rb +0 -32
- data/lib/graphql/define/instance_definable.rb +0 -79
- data/lib/graphql/define/non_null_with_bang.rb +0 -15
- data/lib/graphql/define/type_definer.rb +0 -30
- data/lib/graphql/define.rb +0 -8
- data/lib/graphql/directive/include_directive.rb +0 -10
- data/lib/graphql/directive/skip_directive.rb +0 -11
- data/lib/graphql/directive.rb +0 -49
- data/lib/graphql/enum_type.rb +0 -95
- data/lib/graphql/field.rb +0 -131
- data/lib/graphql/float_type.rb +0 -5
- data/lib/graphql/id_type.rb +0 -12
- data/lib/graphql/input_object_type.rb +0 -71
- data/lib/graphql/int_type.rb +0 -5
- data/lib/graphql/interface_type.rb +0 -38
- data/lib/graphql/internal_representation/node.rb +0 -81
- data/lib/graphql/internal_representation/rewrite.rb +0 -177
- data/lib/graphql/internal_representation.rb +0 -2
- data/lib/graphql/introspection/arguments_field.rb +0 -5
- data/lib/graphql/introspection/enum_values_field.rb +0 -13
- data/lib/graphql/introspection/fields_field.rb +0 -13
- data/lib/graphql/introspection/input_fields_field.rb +0 -12
- data/lib/graphql/introspection/interfaces_field.rb +0 -5
- data/lib/graphql/introspection/of_type_field.rb +0 -6
- data/lib/graphql/introspection/possible_types_field.rb +0 -11
- data/lib/graphql/introspection/schema_field.rb +0 -15
- data/lib/graphql/introspection/type_by_name_field.rb +0 -16
- data/lib/graphql/introspection/typename_field.rb +0 -15
- data/lib/graphql/list_type.rb +0 -46
- data/lib/graphql/non_null_type.rb +0 -43
- data/lib/graphql/object_type.rb +0 -93
- data/lib/graphql/query/arguments.rb +0 -76
- data/lib/graphql/query/directive_resolution.rb +0 -16
- data/lib/graphql/query/executor.rb +0 -45
- data/lib/graphql/query/literal_input.rb +0 -90
- data/lib/graphql/query/serial_execution/execution_context.rb +0 -31
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -82
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -27
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -42
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -107
- data/lib/graphql/query/serial_execution.rb +0 -41
- data/lib/graphql/query/type_resolver.rb +0 -25
- data/lib/graphql/scalar_type.rb +0 -53
- data/lib/graphql/schema/catchall_middleware.rb +0 -34
- data/lib/graphql/schema/middleware_chain.rb +0 -28
- data/lib/graphql/schema/possible_types.rb +0 -34
- data/lib/graphql/schema/reduce_types.rb +0 -68
- data/lib/graphql/schema/rescue_middleware.rb +0 -53
- data/lib/graphql/schema/timeout_middleware.rb +0 -67
- data/lib/graphql/schema/type_map.rb +0 -30
- data/lib/graphql/schema/validation.rb +0 -164
- data/lib/graphql/static_validation/arguments_validator.rb +0 -48
- data/lib/graphql/static_validation/message.rb +0 -36
- data/lib/graphql/string_type.rb +0 -5
- data/lib/graphql/union_type.rb +0 -38
- data/spec/graphql/analysis/analyze_query_spec.rb +0 -50
- data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -62
- data/spec/graphql/analysis/max_query_depth_spec.rb +0 -100
- data/spec/graphql/analysis/query_complexity_spec.rb +0 -235
- data/spec/graphql/analysis/query_depth_spec.rb +0 -80
- data/spec/graphql/argument_spec.rb +0 -20
- data/spec/graphql/base_type_spec.rb +0 -24
- data/spec/graphql/boolean_type_spec.rb +0 -20
- data/spec/graphql/define/instance_definable_spec.rb +0 -55
- data/spec/graphql/directive_spec.rb +0 -77
- data/spec/graphql/enum_type_spec.rb +0 -31
- data/spec/graphql/execution_error_spec.rb +0 -61
- data/spec/graphql/field_spec.rb +0 -92
- data/spec/graphql/float_type_spec.rb +0 -15
- data/spec/graphql/id_type_spec.rb +0 -32
- data/spec/graphql/input_object_type_spec.rb +0 -162
- data/spec/graphql/int_type_spec.rb +0 -15
- data/spec/graphql/interface_type_spec.rb +0 -56
- data/spec/graphql/internal_representation/rewrite_spec.rb +0 -120
- data/spec/graphql/introspection/directive_type_spec.rb +0 -50
- data/spec/graphql/introspection/input_value_type_spec.rb +0 -42
- data/spec/graphql/introspection/introspection_query_spec.rb +0 -10
- data/spec/graphql/introspection/schema_type_spec.rb +0 -45
- data/spec/graphql/introspection/type_type_spec.rb +0 -122
- data/spec/graphql/language/generation_spec.rb +0 -42
- data/spec/graphql/language/parser_spec.rb +0 -442
- data/spec/graphql/language/visitor_spec.rb +0 -49
- data/spec/graphql/list_type_spec.rb +0 -32
- data/spec/graphql/non_null_type_spec.rb +0 -31
- data/spec/graphql/object_type_spec.rb +0 -42
- data/spec/graphql/query/arguments_spec.rb +0 -25
- data/spec/graphql/query/context_spec.rb +0 -83
- data/spec/graphql/query/executor_spec.rb +0 -273
- data/spec/graphql/query/serial_execution/execution_context_spec.rb +0 -53
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -66
- data/spec/graphql/query/type_resolver_spec.rb +0 -8
- data/spec/graphql/query/variables_spec.rb +0 -28
- data/spec/graphql/query_spec.rb +0 -363
- data/spec/graphql/scalar_type_spec.rb +0 -61
- data/spec/graphql/schema/catchall_middleware_spec.rb +0 -32
- data/spec/graphql/schema/middleware_chain_spec.rb +0 -42
- data/spec/graphql/schema/printer_spec.rb +0 -190
- data/spec/graphql/schema/reduce_types_spec.rb +0 -102
- data/spec/graphql/schema/rescue_middleware_spec.rb +0 -33
- data/spec/graphql/schema/timeout_middleware_spec.rb +0 -180
- data/spec/graphql/schema/type_expression_spec.rb +0 -38
- data/spec/graphql/schema/validation_spec.rb +0 -219
- data/spec/graphql/schema_spec.rb +0 -23
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -63
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -48
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -34
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -39
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -60
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -31
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -48
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -47
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -39
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -44
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -49
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -25
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -42
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -44
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -63
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -37
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -53
- data/spec/graphql/static_validation/type_stack_spec.rb +0 -37
- data/spec/graphql/static_validation/validator_spec.rb +0 -69
- data/spec/graphql/string_type_spec.rb +0 -15
- data/spec/graphql/union_type_spec.rb +0 -31
- data/spec/spec_helper.rb +0 -18
- data/spec/support/dairy_app.rb +0 -309
- data/spec/support/dairy_data.rb +0 -23
- data/spec/support/minimum_input_object.rb +0 -16
- data/spec/support/star_wars_data.rb +0 -71
- data/spec/support/star_wars_schema.rb +0 -76
@@ -1,15 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
class Query
|
3
4
|
# Expose some query-specific info to field resolve functions.
|
4
5
|
# It delegates `[]` to the hash that's passed to `GraphQL::Query#initialize`.
|
5
6
|
class Context
|
6
|
-
|
7
|
+
module SharedMethods
|
8
|
+
# Return this value to tell the runtime
|
9
|
+
# to exclude this field from the response altogether
|
10
|
+
def skip
|
11
|
+
GraphQL::Execution::SKIP
|
12
|
+
end
|
7
13
|
|
8
|
-
|
9
|
-
|
14
|
+
# Add error at query-level.
|
15
|
+
# @param error [GraphQL::ExecutionError] an execution error
|
16
|
+
# @return [void]
|
17
|
+
def add_error(error)
|
18
|
+
if !error.is_a?(ExecutionError)
|
19
|
+
raise TypeError, "expected error to be a ExecutionError, but was #{error.class}"
|
20
|
+
end
|
21
|
+
errors << error
|
22
|
+
nil
|
23
|
+
end
|
10
24
|
|
11
|
-
|
12
|
-
|
25
|
+
# @example Print the GraphQL backtrace during field resolution
|
26
|
+
# puts ctx.backtrace
|
27
|
+
#
|
28
|
+
# @return [GraphQL::Backtrace] The backtrace for this point in query execution
|
29
|
+
def backtrace
|
30
|
+
GraphQL::Backtrace.new(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def execution_errors
|
34
|
+
@execution_errors ||= ExecutionErrors.new(self)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class ExecutionErrors
|
39
|
+
def initialize(ctx)
|
40
|
+
@context = ctx
|
41
|
+
end
|
42
|
+
|
43
|
+
def add(err_or_msg)
|
44
|
+
err = case err_or_msg
|
45
|
+
when String
|
46
|
+
GraphQL::ExecutionError.new(err_or_msg)
|
47
|
+
when GraphQL::ExecutionError
|
48
|
+
err_or_msg
|
49
|
+
else
|
50
|
+
raise ArgumentError, "expected String or GraphQL::ExecutionError, not #{err_or_msg.class} (#{err_or_msg.inspect})"
|
51
|
+
end
|
52
|
+
# This will assign ast_node and path
|
53
|
+
@context.add_error(err)
|
54
|
+
end
|
55
|
+
|
56
|
+
alias :>> :add
|
57
|
+
alias :push :add
|
58
|
+
end
|
59
|
+
|
60
|
+
include SharedMethods
|
61
|
+
extend Forwardable
|
13
62
|
|
14
63
|
# @return [Array<GraphQL::ExecutionError>] errors returned during execution
|
15
64
|
attr_reader :errors
|
@@ -20,24 +69,229 @@ module GraphQL
|
|
20
69
|
# @return [GraphQL::Schema]
|
21
70
|
attr_reader :schema
|
22
71
|
|
72
|
+
# @return [Array<String, Integer>] The current position in the result
|
73
|
+
attr_reader :path
|
74
|
+
|
23
75
|
# Make a new context which delegates key lookup to `values`
|
24
76
|
# @param query [GraphQL::Query] the query who owns this context
|
25
77
|
# @param values [Hash] A hash of arbitrary values which will be accessible at query-time
|
26
|
-
def initialize(query:, values:)
|
78
|
+
def initialize(query:, schema: query.schema, values:, object:)
|
27
79
|
@query = query
|
28
|
-
@schema =
|
29
|
-
@
|
80
|
+
@schema = schema
|
81
|
+
@provided_values = values || {}
|
82
|
+
@object = object
|
83
|
+
# Namespaced storage, where user-provided values are in `nil` namespace:
|
84
|
+
@storage = Hash.new { |h, k| h[k] = {} }
|
85
|
+
@storage[nil] = @provided_values
|
30
86
|
@errors = []
|
87
|
+
@path = []
|
88
|
+
@value = nil
|
89
|
+
@context = self # for SharedMethods TODO delete sharedmethods
|
90
|
+
@scoped_context = ScopedContext.new(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
class ScopedContext
|
94
|
+
def initialize(query_context)
|
95
|
+
@query_context = query_context
|
96
|
+
@path_contexts = {}
|
97
|
+
@no_path = [].freeze
|
98
|
+
end
|
99
|
+
|
100
|
+
def merged_context
|
101
|
+
merged_ctx = {}
|
102
|
+
each_present_path_ctx do |path_ctx|
|
103
|
+
merged_ctx = path_ctx.merge(merged_ctx)
|
104
|
+
end
|
105
|
+
merged_ctx
|
106
|
+
end
|
107
|
+
|
108
|
+
def merge!(hash)
|
109
|
+
current_ctx = @path_contexts[current_path] ||= {}
|
110
|
+
current_ctx.merge!(hash)
|
111
|
+
end
|
112
|
+
|
113
|
+
def current_path
|
114
|
+
@query_context[:current_path] || @no_path
|
115
|
+
end
|
116
|
+
|
117
|
+
def key?(key)
|
118
|
+
each_present_path_ctx do |path_ctx|
|
119
|
+
if path_ctx.key?(key)
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
false
|
124
|
+
end
|
125
|
+
|
126
|
+
def [](key)
|
127
|
+
each_present_path_ctx do |path_ctx|
|
128
|
+
if path_ctx.key?(key)
|
129
|
+
return path_ctx[key]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
def dig(key, *other_keys)
|
136
|
+
each_present_path_ctx do |path_ctx|
|
137
|
+
if path_ctx.key?(key)
|
138
|
+
found_value = path_ctx[key]
|
139
|
+
if other_keys.any?
|
140
|
+
return found_value.dig(*other_keys)
|
141
|
+
else
|
142
|
+
return found_value
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
# Start at the current location,
|
152
|
+
# but look up the tree for previously-assigned scoped values
|
153
|
+
def each_present_path_ctx
|
154
|
+
search_path = current_path.dup
|
155
|
+
if (current_path_ctx = @path_contexts[search_path])
|
156
|
+
yield(current_path_ctx)
|
157
|
+
end
|
158
|
+
|
159
|
+
while search_path.size > 0
|
160
|
+
search_path.pop # look one level higher
|
161
|
+
if (search_path_ctx = @path_contexts[search_path])
|
162
|
+
yield(search_path_ctx)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# @return [Hash] A hash that will be added verbatim to the result hash, as `"extensions" => { ... }`
|
169
|
+
def response_extensions
|
170
|
+
namespace(:__query_result_extensions__)
|
31
171
|
end
|
32
172
|
|
173
|
+
def dataloader
|
174
|
+
@dataloader ||= self[:dataloader] || (query.multiplex ? query.multiplex.dataloader : schema.dataloader_class.new)
|
175
|
+
end
|
176
|
+
|
177
|
+
# @api private
|
178
|
+
attr_writer :interpreter
|
179
|
+
|
180
|
+
# @api private
|
181
|
+
attr_writer :value
|
182
|
+
|
183
|
+
# @api private
|
184
|
+
attr_reader :scoped_context
|
185
|
+
|
186
|
+
def []=(key, value)
|
187
|
+
@provided_values[key] = value
|
188
|
+
end
|
189
|
+
|
190
|
+
def_delegators :@query, :trace, :interpreter?
|
191
|
+
|
192
|
+
RUNTIME_METADATA_KEYS = Set.new([:current_object, :current_arguments, :current_field, :current_path])
|
193
|
+
# @!method []=(key, value)
|
194
|
+
# Reassign `key` to the hash passed to {Schema#execute} as `context:`
|
195
|
+
|
33
196
|
# Lookup `key` from the hash passed to {Schema#execute} as `context:`
|
34
197
|
def [](key)
|
35
|
-
|
198
|
+
if RUNTIME_METADATA_KEYS.include?(key)
|
199
|
+
thread_info = Thread.current[:__graphql_runtime_info]
|
200
|
+
thread_info && thread_info[key]
|
201
|
+
elsif @scoped_context.key?(key)
|
202
|
+
@scoped_context[key]
|
203
|
+
else
|
204
|
+
@provided_values[key]
|
205
|
+
end
|
36
206
|
end
|
37
207
|
|
38
|
-
|
39
|
-
|
40
|
-
|
208
|
+
def delete(key)
|
209
|
+
if @scoped_context.key?(key)
|
210
|
+
@scoped_context.delete(key)
|
211
|
+
else
|
212
|
+
@provided_values.delete(key)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
UNSPECIFIED_FETCH_DEFAULT = Object.new
|
217
|
+
|
218
|
+
def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
|
219
|
+
if RUNTIME_METADATA_KEYS.include?(key)
|
220
|
+
(thread_info = Thread.current[:__graphql_runtime_info]) &&
|
221
|
+
thread_info[key]
|
222
|
+
elsif @scoped_context.key?(key)
|
223
|
+
scoped_context[key]
|
224
|
+
elsif @provided_values.key?(key)
|
225
|
+
@provided_values[key]
|
226
|
+
elsif default != UNSPECIFIED_FETCH_DEFAULT
|
227
|
+
default
|
228
|
+
elsif block_given?
|
229
|
+
yield(self, key)
|
230
|
+
else
|
231
|
+
raise KeyError.new(key: key)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def dig(key, *other_keys)
|
236
|
+
if RUNTIME_METADATA_KEYS.include?(key)
|
237
|
+
(thread_info = Thread.current[:__graphql_runtime_info]).key?(key) &&
|
238
|
+
thread_info.dig(key)
|
239
|
+
elsif @scoped_context.key?(key)
|
240
|
+
@scoped_context.dig(key, *other_keys)
|
241
|
+
else
|
242
|
+
@provided_values.dig(key, *other_keys)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def to_h
|
247
|
+
if (current_scoped_context = @scoped_context.merged_context)
|
248
|
+
@provided_values.merge(current_scoped_context)
|
249
|
+
else
|
250
|
+
@provided_values
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
alias :to_hash :to_h
|
255
|
+
|
256
|
+
def key?(key)
|
257
|
+
@scoped_context.key?(key) || @provided_values.key?(key)
|
258
|
+
end
|
259
|
+
|
260
|
+
# @return [GraphQL::Schema::Warden]
|
261
|
+
def warden
|
262
|
+
@warden ||= (@query && @query.warden)
|
263
|
+
end
|
264
|
+
|
265
|
+
# @api private
|
266
|
+
attr_writer :warden
|
267
|
+
|
268
|
+
# Get an isolated hash for `ns`. Doesn't affect user-provided storage.
|
269
|
+
# @param ns [Object] a usage-specific namespace identifier
|
270
|
+
# @return [Hash] namespaced storage
|
271
|
+
def namespace(ns)
|
272
|
+
if ns == :interpreter
|
273
|
+
self
|
274
|
+
else
|
275
|
+
@storage[ns]
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# @return [Boolean] true if this namespace was accessed before
|
280
|
+
def namespace?(ns)
|
281
|
+
@storage.key?(ns)
|
282
|
+
end
|
283
|
+
|
284
|
+
def inspect
|
285
|
+
"#<Query::Context ...>"
|
286
|
+
end
|
287
|
+
|
288
|
+
def scoped_merge!(hash)
|
289
|
+
@scoped_context.merge!(hash)
|
290
|
+
end
|
291
|
+
|
292
|
+
def scoped_set!(key, value)
|
293
|
+
scoped_merge!(key => value)
|
294
|
+
nil
|
41
295
|
end
|
42
296
|
end
|
43
297
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest/sha2'
|
4
|
+
|
5
|
+
module GraphQL
|
6
|
+
class Query
|
7
|
+
# @api private
|
8
|
+
# @see Query#query_fingerprint
|
9
|
+
# @see Query#variables_fingerprint
|
10
|
+
# @see Query#fingerprint
|
11
|
+
module Fingerprint
|
12
|
+
# Make an obfuscated hash of the given string (either a query string or variables JSON)
|
13
|
+
# @param string [String]
|
14
|
+
# @return [String] A normalized, opaque hash
|
15
|
+
def self.generate(input_str)
|
16
|
+
# Implemented to be:
|
17
|
+
# - Short (and uniform) length
|
18
|
+
# - Stable
|
19
|
+
# - Irreversibly Opaque (don't want to leak variable values)
|
20
|
+
# - URL-friendly
|
21
|
+
bytes = Digest::SHA256.digest(input_str)
|
22
|
+
Base64.urlsafe_encode64(bytes)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,25 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
class Query
|
3
4
|
class InputValidationResult
|
4
5
|
attr_accessor :problems
|
5
6
|
|
7
|
+
def self.from_problem(explanation, path = nil, extensions: nil, message: nil)
|
8
|
+
result = self.new
|
9
|
+
result.add_problem(explanation, path, extensions: extensions, message: message)
|
10
|
+
result
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(valid: true, problems: nil)
|
14
|
+
@valid = valid
|
15
|
+
@problems = problems
|
16
|
+
end
|
17
|
+
|
6
18
|
def valid?
|
7
|
-
@
|
19
|
+
@valid
|
8
20
|
end
|
9
21
|
|
10
|
-
def add_problem(explanation, path = nil)
|
22
|
+
def add_problem(explanation, path = nil, extensions: nil, message: nil)
|
11
23
|
@problems ||= []
|
12
|
-
@
|
24
|
+
@valid = false
|
25
|
+
problem = { "path" => path || [], "explanation" => explanation }
|
26
|
+
if extensions
|
27
|
+
problem["extensions"] = extensions
|
28
|
+
end
|
29
|
+
if message
|
30
|
+
problem["message"] = message
|
31
|
+
end
|
32
|
+
@problems.push(problem)
|
13
33
|
end
|
14
34
|
|
15
35
|
def merge_result!(path, inner_result)
|
16
|
-
return if inner_result.valid?
|
36
|
+
return if inner_result.nil? || inner_result.valid?
|
17
37
|
|
18
|
-
inner_result.problems
|
19
|
-
|
20
|
-
|
38
|
+
if inner_result.problems
|
39
|
+
inner_result.problems.each do |p|
|
40
|
+
item_path = [path, *p["path"]]
|
41
|
+
add_problem(p["explanation"], item_path, message: p["message"], extensions: p["extensions"])
|
42
|
+
end
|
21
43
|
end
|
44
|
+
# It could have been explicitly set on inner_result (if it had no problems)
|
45
|
+
@valid = false
|
22
46
|
end
|
47
|
+
|
48
|
+
VALID = self.new
|
49
|
+
VALID.freeze
|
23
50
|
end
|
24
51
|
end
|
25
52
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Query
|
4
|
+
# This object can be `ctx` in places where there is no query
|
5
|
+
class NullContext
|
6
|
+
class NullWarden < GraphQL::Schema::Warden
|
7
|
+
def visible_field?(field, ctx); true; end
|
8
|
+
def visible_argument?(arg, ctx); true; end
|
9
|
+
def visible_type?(type, ctx); true; end
|
10
|
+
def visible_enum_value?(ev, ctx); true; end
|
11
|
+
def visible_type_membership?(tm, ctx); true; end
|
12
|
+
end
|
13
|
+
|
14
|
+
class NullQuery
|
15
|
+
end
|
16
|
+
|
17
|
+
class NullSchema < GraphQL::Schema
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :schema, :query, :warden, :dataloader
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@query = NullQuery.new
|
24
|
+
@dataloader = GraphQL::Dataloader::NullDataloader.new
|
25
|
+
@schema = NullSchema
|
26
|
+
@warden = NullWarden.new(
|
27
|
+
GraphQL::Filter.new,
|
28
|
+
context: self,
|
29
|
+
schema: @schema,
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def [](key); end
|
34
|
+
|
35
|
+
def interpreter?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
extend Forwardable
|
41
|
+
|
42
|
+
def [](key); end
|
43
|
+
|
44
|
+
def instance
|
45
|
+
@instance ||= self.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def_delegators :instance, :query, :warden, :schema, :interpreter?, :dataloader
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Query
|
5
|
+
# A result from {Schema#execute}.
|
6
|
+
# It provides the requested data and
|
7
|
+
# access to the {Query} and {Query::Context}.
|
8
|
+
class Result
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def initialize(query:, values:)
|
12
|
+
@query = query
|
13
|
+
@to_h = values
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [GraphQL::Query] The query that was executed
|
17
|
+
attr_reader :query
|
18
|
+
|
19
|
+
# @return [Hash] The resulting hash of "data" and/or "errors"
|
20
|
+
attr_reader :to_h
|
21
|
+
|
22
|
+
def_delegators :@query, :context, :mutation?, :query?, :subscription?
|
23
|
+
|
24
|
+
def_delegators :@to_h, :[], :keys, :values, :to_json, :as_json
|
25
|
+
|
26
|
+
# Delegate any hash-like method to the underlying hash.
|
27
|
+
def method_missing(method_name, *args, &block)
|
28
|
+
if @to_h.respond_to?(method_name)
|
29
|
+
@to_h.public_send(method_name, *args, &block)
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def respond_to_missing?(method_name, include_private = false)
|
36
|
+
@to_h.respond_to?(method_name) || super
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
"#<GraphQL::Query::Result @query=... @to_h=#{@to_h}>"
|
41
|
+
end
|
42
|
+
|
43
|
+
# A result is equal to another object when:
|
44
|
+
#
|
45
|
+
# - The other object is a Hash whose value matches `result.to_h`
|
46
|
+
# - The other object is a Result whose value matches `result.to_h`
|
47
|
+
#
|
48
|
+
# (The query is ignored for comparing result equality.)
|
49
|
+
#
|
50
|
+
# @return [Boolean]
|
51
|
+
def ==(other)
|
52
|
+
case other
|
53
|
+
when Hash
|
54
|
+
@to_h == other
|
55
|
+
when Query::Result
|
56
|
+
@to_h == other.to_h
|
57
|
+
else
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Query
|
4
|
+
# Contain the validation pipeline and expose the results.
|
5
|
+
#
|
6
|
+
# 0. Checks in {Query#initialize}:
|
7
|
+
# - Rescue a ParseError, halt if there is one
|
8
|
+
# - Check for selected operation, halt if not found
|
9
|
+
# 1. Validate the AST, halt if errors
|
10
|
+
# 2. Validate the variables, halt if errors
|
11
|
+
# 3. Run query analyzers, halt if errors
|
12
|
+
#
|
13
|
+
# {#valid?} is false if any of the above checks halted the pipeline.
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
class ValidationPipeline
|
17
|
+
attr_reader :max_depth, :max_complexity
|
18
|
+
|
19
|
+
def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
|
20
|
+
@validation_errors = []
|
21
|
+
@parse_error = parse_error
|
22
|
+
@operation_name_error = operation_name_error
|
23
|
+
@query = query
|
24
|
+
@schema = query.schema
|
25
|
+
@max_depth = max_depth
|
26
|
+
@max_complexity = max_complexity
|
27
|
+
|
28
|
+
@has_validated = false
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Boolean] does this query have errors that should prevent it from running?
|
32
|
+
def valid?
|
33
|
+
ensure_has_validated
|
34
|
+
@valid
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Array<GraphQL::StaticValidation::Error, GraphQL::Query::VariableValidationError>] Static validation errors for the query string
|
38
|
+
def validation_errors
|
39
|
+
ensure_has_validated
|
40
|
+
@validation_errors
|
41
|
+
end
|
42
|
+
|
43
|
+
def analyzers
|
44
|
+
ensure_has_validated
|
45
|
+
@query_analyzers
|
46
|
+
end
|
47
|
+
|
48
|
+
def has_validated?
|
49
|
+
@has_validated == true
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# If the pipeline wasn't run yet, run it.
|
55
|
+
# If it was already run, do nothing.
|
56
|
+
def ensure_has_validated
|
57
|
+
return if @has_validated
|
58
|
+
@has_validated = true
|
59
|
+
|
60
|
+
if @parse_error
|
61
|
+
# This is kind of crazy: we push the parse error into `ctx`
|
62
|
+
# in `def self.parse_error` by default so that users can _opt out_ by redefining that hook.
|
63
|
+
# That means we can't _re-add_ the error here (otherwise we'd either
|
64
|
+
# add it twice _or_ override the user's choice to not add it).
|
65
|
+
# So we just have to know that it was invalid and go from there.
|
66
|
+
@valid = false
|
67
|
+
return
|
68
|
+
elsif @operation_name_error
|
69
|
+
@validation_errors << @operation_name_error
|
70
|
+
else
|
71
|
+
validation_result = @schema.static_validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
|
72
|
+
@validation_errors.concat(validation_result[:errors])
|
73
|
+
|
74
|
+
if @validation_errors.empty?
|
75
|
+
@validation_errors.concat(@query.variables.errors)
|
76
|
+
end
|
77
|
+
|
78
|
+
if @validation_errors.empty?
|
79
|
+
@query_analyzers = build_analyzers(
|
80
|
+
@schema,
|
81
|
+
@max_depth,
|
82
|
+
@max_complexity
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@valid = @validation_errors.empty?
|
88
|
+
rescue SystemStackError => err
|
89
|
+
@valid = false
|
90
|
+
@schema.query_stack_error(@query, err)
|
91
|
+
end
|
92
|
+
|
93
|
+
# If there are max_* values, add them,
|
94
|
+
# otherwise reuse the schema's list of analyzers.
|
95
|
+
def build_analyzers(schema, max_depth, max_complexity)
|
96
|
+
qa = schema.query_analyzers.dup
|
97
|
+
|
98
|
+
if max_depth || max_complexity
|
99
|
+
# Depending on the analysis engine, we must use different analyzers
|
100
|
+
# remove this once everything has switched over to AST analyzers
|
101
|
+
if max_depth
|
102
|
+
qa << GraphQL::Analysis::AST::MaxQueryDepth
|
103
|
+
end
|
104
|
+
if max_complexity
|
105
|
+
qa << GraphQL::Analysis::AST::MaxQueryComplexity
|
106
|
+
end
|
107
|
+
qa
|
108
|
+
else
|
109
|
+
qa
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -1,19 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
class Query
|
3
4
|
class VariableValidationError < GraphQL::ExecutionError
|
4
5
|
attr_accessor :value, :validation_result
|
5
6
|
|
6
|
-
def initialize(variable_ast, type, value, validation_result)
|
7
|
+
def initialize(variable_ast, type, value, validation_result, msg: nil)
|
7
8
|
@value = value
|
8
9
|
@validation_result = validation_result
|
9
10
|
|
10
|
-
msg
|
11
|
+
msg ||= "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
|
12
|
+
|
13
|
+
if problem_fields.any?
|
14
|
+
msg += " for #{problem_fields.join(", ")}"
|
15
|
+
end
|
16
|
+
|
11
17
|
super(msg)
|
12
18
|
self.ast_node = variable_ast
|
13
19
|
end
|
14
20
|
|
15
21
|
def to_h
|
16
|
-
|
22
|
+
# It is possible there are other extension items in this error, so handle
|
23
|
+
# a one level deep merge explicitly. However beyond that only show the
|
24
|
+
# latest value and problems.
|
25
|
+
super.merge({ "extensions" => { "value" => value, "problems" => validation_result.problems }}) do |key, oldValue, newValue|
|
26
|
+
if oldValue.respond_to?(:merge)
|
27
|
+
oldValue.merge(newValue)
|
28
|
+
else
|
29
|
+
newValue
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def problem_fields
|
37
|
+
@problem_fields ||= @validation_result
|
38
|
+
.problems
|
39
|
+
.reject { |problem| problem["path"].empty? }
|
40
|
+
.map { |problem| "#{problem['path'].join('.')} (#{problem['explanation']})" }
|
17
41
|
end
|
18
42
|
end
|
19
43
|
end
|