graphql 1.9.17 → 2.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +45 -8
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +49 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +25 -27
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +31 -2
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +54 -38
- data/lib/graphql/analysis/ast.rb +16 -16
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +37 -16
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +26 -18
- data/lib/graphql/dataloader/null_dataloader.rb +24 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +164 -0
- data/lib/graphql/dataloader.rb +311 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +77 -45
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +104 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +62 -24
- data/lib/graphql/execution/interpreter/runtime.rb +830 -417
- data/lib/graphql/execution/interpreter.rb +206 -74
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +65 -136
- data/lib/graphql/execution/multiplex.rb +6 -152
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +8 -3
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/base_object.rb +2 -5
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +12 -6
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +5 -18
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +41 -11
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +12 -12
- data/lib/graphql/introspection/type_type.rb +34 -17
- data/lib/graphql/introspection.rb +100 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +136 -78
- data/lib/graphql/language/lexer.rb +216 -1462
- data/lib/graphql/language/nodes.rb +129 -132
- data/lib/graphql/language/parser.rb +994 -932
- data/lib/graphql/language/parser.y +152 -120
- data/lib/graphql/language/printer.rb +48 -23
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +192 -84
- data/lib/graphql/language.rb +3 -1
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +77 -0
- data/lib/graphql/pagination/array_connection.rb +79 -0
- data/lib/graphql/pagination/connection.rb +253 -0
- data/lib/graphql/pagination/connections.rb +135 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +228 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +205 -203
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +33 -7
- data/lib/graphql/query/null_context.rb +22 -9
- data/lib/graphql/query/validation_pipeline.rb +16 -38
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +39 -12
- data/lib/graphql/query.rb +95 -43
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +4 -1
- data/lib/graphql/rake_task.rb +41 -10
- data/lib/graphql/relay/range_add.rb +17 -10
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/schema/addition.rb +245 -0
- data/lib/graphql/schema/argument.rb +285 -36
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
- data/lib/graphql/schema/build_from_definition.rb +348 -205
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +2 -2
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +2 -2
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +134 -15
- data/lib/graphql/schema/enum.rb +137 -39
- data/lib/graphql/schema/enum_value.rb +17 -23
- data/lib/graphql/schema/field/connection_extension.rb +50 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +504 -331
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +12 -1
- data/lib/graphql/schema/finder.rb +16 -14
- data/lib/graphql/schema/input_object.rb +182 -60
- data/lib/graphql/schema/interface.rb +24 -49
- data/lib/graphql/schema/introspection_system.rb +103 -37
- data/lib/graphql/schema/late_bound_type.rb +9 -2
- data/lib/graphql/schema/list.rb +61 -3
- data/lib/graphql/schema/loader.rb +144 -96
- data/lib/graphql/schema/member/base_dsl_methods.rb +41 -37
- data/lib/graphql/schema/member/build_type.rb +24 -15
- data/lib/graphql/schema/member/has_arguments.rb +310 -26
- data/lib/graphql/schema/member/has_ast_node.rb +32 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
- data/lib/graphql/schema/member/has_directives.rb +118 -0
- data/lib/graphql/schema/member/has_fields.rb +166 -44
- data/lib/graphql/schema/member/has_interfaces.rb +129 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +57 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +11 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +34 -4
- data/lib/graphql/schema/object.rb +36 -60
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +91 -44
- data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
- data/lib/graphql/schema/resolver.rb +147 -94
- data/lib/graphql/schema/scalar.rb +40 -15
- data/lib/graphql/schema/subscription.rb +60 -31
- data/lib/graphql/schema/timeout.rb +45 -35
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +23 -6
- data/lib/graphql/schema/union.rb +49 -15
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +213 -35
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +857 -884
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +21 -31
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +69 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +15 -7
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +96 -53
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +32 -20
- data/lib/graphql/static_validation.rb +1 -2
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +129 -22
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +84 -35
- data/lib/graphql/subscriptions/instrumentation.rb +0 -47
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +137 -57
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +34 -2
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +76 -35
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
- data/lib/graphql/tracing/prometheus_tracing.rb +11 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +23 -67
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +20 -9
- data/lib/graphql/types/iso_8601_date_time.rb +36 -10
- data/lib/graphql/types/relay/base_connection.rb +18 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +75 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +25 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
- data/lib/graphql/types/relay.rb +10 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +63 -65
- data/readme.md +3 -6
- metadata +127 -236
- data/lib/graphql/analysis/analyze_query.rb +0 -91
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -159
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -226
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -435
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -50
- data/lib/graphql/define/instance_definable.rb +0 -300
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -42
- data/lib/graphql/directive/deprecated_directive.rb +0 -13
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -104
- data/lib/graphql/enum_type.rb +0 -193
- data/lib/graphql/execution/execute.rb +0 -326
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -330
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -153
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -154
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -86
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -258
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/non_null_type.rb +0 -81
- data/lib/graphql/object_type.rb +0 -141
- data/lib/graphql/query/arguments.rb +0 -187
- data/lib/graphql/query/arguments_cache.rb +0 -25
- data/lib/graphql/query/executor.rb +0 -53
- data/lib/graphql/query/literal_input.rb +0 -116
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -39
- data/lib/graphql/relay/array_connection.rb +0 -85
- data/lib/graphql/relay/base_connection.rb +0 -172
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -40
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -18
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -190
- data/lib/graphql/relay/node.rb +0 -36
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -133
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -15
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
- data/lib/graphql/schema/member/instrumentation.rb +0 -132
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -39
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -86
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -303
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -66
- data/lib/graphql/tracing/skylight_tracing.rb +0 -62
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
- data/lib/graphql/types/relay/node_field.rb +0 -43
- data/lib/graphql/types/relay/nodes_field.rb +0 -45
- data/lib/graphql/union_type.rb +0 -128
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "delegate"
|
3
|
-
|
4
|
-
module GraphQL
|
5
|
-
class Schema
|
6
|
-
# This middleware will stop resolving new fields after `max_seconds` have elapsed.
|
7
|
-
# After the time has passed, any remaining fields will be `nil`, with errors added
|
8
|
-
# to the `errors` key. Any already-resolved fields will be in the `data` key, so
|
9
|
-
# you'll get a partial response.
|
10
|
-
#
|
11
|
-
# You can provide a block which will be called with any timeout errors that occur.
|
12
|
-
#
|
13
|
-
# Note that this will stop a query _in between_ field resolutions, but
|
14
|
-
# it doesn't interrupt long-running `resolve` functions. Be sure to use
|
15
|
-
# timeout options for external connections. For more info, see
|
16
|
-
# www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/
|
17
|
-
#
|
18
|
-
# @example Stop resolving fields after 2 seconds
|
19
|
-
# MySchema.middleware << GraphQL::Schema::TimeoutMiddleware.new(max_seconds: 2)
|
20
|
-
#
|
21
|
-
# @example Notifying Bugsnag on a timeout
|
22
|
-
# MySchema.middleware << GraphQL::Schema::TimeoutMiddleware(max_seconds: 1.5) do |timeout_error, query|
|
23
|
-
# Bugsnag.notify(timeout_error, {query_string: query_ctx.query.query_string})
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
class TimeoutMiddleware
|
27
|
-
# @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
|
28
|
-
def initialize(max_seconds:, context_key: nil, &block)
|
29
|
-
@max_seconds = max_seconds
|
30
|
-
if context_key
|
31
|
-
warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
|
32
|
-
end
|
33
|
-
@error_handler = block
|
34
|
-
end
|
35
|
-
|
36
|
-
def call(parent_type, parent_object, field_definition, field_args, query_context)
|
37
|
-
ns = query_context.namespace(self.class)
|
38
|
-
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
39
|
-
timeout_at = ns[:timeout_at] ||= now + @max_seconds
|
40
|
-
|
41
|
-
if timeout_at < now
|
42
|
-
on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
|
43
|
-
else
|
44
|
-
yield
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# This is called when a field _would_ be resolved, except that we're over the time limit.
|
49
|
-
# @return [GraphQL::Schema::TimeoutMiddleware::TimeoutError] An error whose message will be added to the `errors` key
|
50
|
-
def on_timeout(parent_type, parent_object, field_definition, field_args, field_context)
|
51
|
-
err = GraphQL::Schema::TimeoutMiddleware::TimeoutError.new(parent_type, field_definition)
|
52
|
-
if @error_handler
|
53
|
-
query_proxy = TimeoutQueryProxy.new(field_context.query, field_context)
|
54
|
-
@error_handler.call(err, query_proxy)
|
55
|
-
end
|
56
|
-
err
|
57
|
-
end
|
58
|
-
|
59
|
-
# This behaves like {GraphQL::Query} but {#context} returns
|
60
|
-
# the _field-level_ context, not the query-level context.
|
61
|
-
# This means you can reliably get the `irep_node` and `path`
|
62
|
-
# from it after the fact.
|
63
|
-
class TimeoutQueryProxy < SimpleDelegator
|
64
|
-
def initialize(query, ctx)
|
65
|
-
@context = ctx
|
66
|
-
super(query)
|
67
|
-
end
|
68
|
-
|
69
|
-
attr_reader :context
|
70
|
-
end
|
71
|
-
|
72
|
-
# This error is raised when a query exceeds `max_seconds`.
|
73
|
-
# Since it's a child of {GraphQL::ExecutionError},
|
74
|
-
# its message will be added to the response's `errors` key.
|
75
|
-
#
|
76
|
-
# To raise an error that will stop query resolution, use a custom block
|
77
|
-
# to take this error and raise a new one which _doesn't_ descend from {GraphQL::ExecutionError},
|
78
|
-
# such as `RuntimeError`.
|
79
|
-
class TimeoutError < GraphQL::ExecutionError
|
80
|
-
def initialize(parent_type, field_defn)
|
81
|
-
super("Timeout on #{parent_type.name}.#{field_defn.name}")
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,228 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# Visit the members of this schema and build up artifacts for runtime.
|
5
|
-
# @api private
|
6
|
-
class Traversal
|
7
|
-
# @return [Hash<String => GraphQL::BaseType]
|
8
|
-
attr_reader :type_map
|
9
|
-
|
10
|
-
# @return [Hash<String => Hash<String => GraphQL::Field>>]
|
11
|
-
attr_reader :instrumented_field_map
|
12
|
-
|
13
|
-
# @return [Hash<String => Array<GraphQL::Field || GraphQL::Argument || GraphQL::Directive>]
|
14
|
-
attr_reader :type_reference_map
|
15
|
-
|
16
|
-
# @return [Hash<String => Array<GraphQL::BaseType>]
|
17
|
-
attr_reader :union_memberships
|
18
|
-
|
19
|
-
|
20
|
-
# @param schema [GraphQL::Schema]
|
21
|
-
def initialize(schema, introspection: true)
|
22
|
-
@schema = schema
|
23
|
-
@introspection = introspection
|
24
|
-
built_in_insts = [
|
25
|
-
GraphQL::Relay::ConnectionInstrumentation,
|
26
|
-
GraphQL::Relay::EdgesInstrumentation,
|
27
|
-
GraphQL::Relay::Mutation::Instrumentation,
|
28
|
-
]
|
29
|
-
|
30
|
-
if schema.query_execution_strategy != GraphQL::Execution::Interpreter
|
31
|
-
built_in_insts << GraphQL::Schema::Member::Instrumentation
|
32
|
-
end
|
33
|
-
|
34
|
-
@field_instrumenters =
|
35
|
-
schema.instrumenters[:field] +
|
36
|
-
built_in_insts +
|
37
|
-
schema.instrumenters[:field_after_built_ins]
|
38
|
-
|
39
|
-
# These fields have types specified by _name_,
|
40
|
-
# So we need to inspect the schema and find those types,
|
41
|
-
# then update their references.
|
42
|
-
@late_bound_fields = []
|
43
|
-
@type_map = {}
|
44
|
-
@instrumented_field_map = Hash.new { |h, k| h[k] = {} }
|
45
|
-
@type_reference_map = Hash.new { |h, k| h[k] = [] }
|
46
|
-
@union_memberships = Hash.new { |h, k| h[k] = [] }
|
47
|
-
visit(schema, schema, nil)
|
48
|
-
resolve_late_bound_fields
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# A brute-force appraoch to late binding.
|
54
|
-
# Just keep trying the whole list, hoping that they
|
55
|
-
# eventually all resolve.
|
56
|
-
# This could be replaced with proper dependency tracking.
|
57
|
-
def resolve_late_bound_fields
|
58
|
-
# This is a bit tricky, with the writes going to internal state.
|
59
|
-
prev_late_bound_fields = @late_bound_fields
|
60
|
-
# Things might get added here during `visit...`
|
61
|
-
# or they might be added manually if we can't find them by hand
|
62
|
-
@late_bound_fields = []
|
63
|
-
prev_late_bound_fields.each do |(owner_type, field_defn, dynamic_field)|
|
64
|
-
if @type_map.key?(field_defn.type.unwrap.name)
|
65
|
-
late_bound_return_type = field_defn.type
|
66
|
-
resolved_type = @type_map.fetch(late_bound_return_type.unwrap.name)
|
67
|
-
wrapped_resolved_type = rewrap_resolved_type(late_bound_return_type, resolved_type)
|
68
|
-
# Update the field definition in place? :thinking_face:
|
69
|
-
field_defn.type = wrapped_resolved_type
|
70
|
-
visit_field_on_type(@schema, owner_type, field_defn, dynamic_field: dynamic_field)
|
71
|
-
else
|
72
|
-
@late_bound_fields << [owner_type, field_defn, dynamic_field]
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
if @late_bound_fields.any?
|
77
|
-
# If we visited each field and failed to resolve _any_,
|
78
|
-
# then we're stuck.
|
79
|
-
if @late_bound_fields == prev_late_bound_fields
|
80
|
-
type_names = prev_late_bound_fields.map { |f| f[1] }.map(&:type).map(&:unwrap).map(&:name).uniq
|
81
|
-
raise <<-ERR
|
82
|
-
Some late-bound types couldn't be resolved:
|
83
|
-
|
84
|
-
- #{type_names}
|
85
|
-
- Found __* types: #{@type_map.keys.select { |k| k.start_with?("__") }}
|
86
|
-
ERR
|
87
|
-
else
|
88
|
-
resolve_late_bound_fields
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# The late-bound type may be wrapped with list or non-null types.
|
94
|
-
# Apply the same wrapping to the resolve type and
|
95
|
-
# return the maybe-wrapped type
|
96
|
-
def rewrap_resolved_type(late_bound_type, resolved_inner_type)
|
97
|
-
case late_bound_type
|
98
|
-
when GraphQL::NonNullType
|
99
|
-
rewrap_resolved_type(late_bound_type.of_type, resolved_inner_type).to_non_null_type
|
100
|
-
when GraphQL::ListType
|
101
|
-
rewrap_resolved_type(late_bound_type.of_type, resolved_inner_type).to_list_type
|
102
|
-
when GraphQL::Schema::LateBoundType
|
103
|
-
resolved_inner_type
|
104
|
-
else
|
105
|
-
raise "Unexpected late_bound_type: #{late_bound_type.inspect} (#{late_bound_type.class})"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def visit(schema, member, context_description)
|
110
|
-
case member
|
111
|
-
when GraphQL::Schema
|
112
|
-
member.directives.each { |name, directive| visit(schema, directive, "Directive #{name}") }
|
113
|
-
# Find the starting points, then visit them
|
114
|
-
visit_roots = [member.query, member.mutation, member.subscription]
|
115
|
-
if @introspection
|
116
|
-
introspection_types = schema.introspection_system.object_types
|
117
|
-
visit_roots.concat(introspection_types)
|
118
|
-
if member.query
|
119
|
-
member.introspection_system.entry_points.each do |introspection_field|
|
120
|
-
# Visit this so that arguments class is preconstructed
|
121
|
-
# Skip validation since it begins with "__"
|
122
|
-
visit_field_on_type(schema, member.query, introspection_field, dynamic_field: true)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
visit_roots.concat(member.orphan_types)
|
127
|
-
visit_roots.compact!
|
128
|
-
visit_roots.each { |t| visit(schema, t, t.name) }
|
129
|
-
when GraphQL::Directive
|
130
|
-
member.arguments.each do |name, argument|
|
131
|
-
@type_reference_map[argument.type.unwrap.to_s] << argument
|
132
|
-
visit(schema, argument.type, "Directive argument #{member.name}.#{name}")
|
133
|
-
end
|
134
|
-
# Construct arguments class here, which is later used to generate GraphQL::Query::Arguments
|
135
|
-
# to be passed to a resolver proc
|
136
|
-
GraphQL::Query::Arguments.construct_arguments_class(member)
|
137
|
-
when GraphQL::BaseType
|
138
|
-
type_defn = member.unwrap
|
139
|
-
prev_type = @type_map[type_defn.name]
|
140
|
-
# Continue to visit this type if it's the first time we've seen it:
|
141
|
-
if prev_type.nil?
|
142
|
-
validate_type(type_defn, context_description)
|
143
|
-
@type_map[type_defn.name] = type_defn
|
144
|
-
case type_defn
|
145
|
-
when GraphQL::ObjectType
|
146
|
-
type_defn.interfaces.each { |i| visit(schema, i, "Interface on #{type_defn.name}") }
|
147
|
-
visit_fields(schema, type_defn)
|
148
|
-
when GraphQL::InterfaceType
|
149
|
-
visit_fields(schema, type_defn)
|
150
|
-
type_defn.orphan_types.each do |t|
|
151
|
-
visit(schema, t, "Orphan type for #{type_defn.name}")
|
152
|
-
end
|
153
|
-
when GraphQL::UnionType
|
154
|
-
type_defn.possible_types.each do |t|
|
155
|
-
@union_memberships[t.name] << type_defn
|
156
|
-
visit(schema, t, "Possible type for #{type_defn.name}")
|
157
|
-
end
|
158
|
-
when GraphQL::InputObjectType
|
159
|
-
type_defn.arguments.each do |name, arg|
|
160
|
-
@type_reference_map[arg.type.unwrap.to_s] << arg
|
161
|
-
visit(schema, arg.type, "Input field #{type_defn.name}.#{name}")
|
162
|
-
end
|
163
|
-
|
164
|
-
# Construct arguments class here, which is later used to generate GraphQL::Query::Arguments
|
165
|
-
# to be passed to a resolver proc
|
166
|
-
if type_defn.arguments_class.nil?
|
167
|
-
GraphQL::Query::Arguments.construct_arguments_class(type_defn)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
elsif !prev_type.equal?(type_defn)
|
171
|
-
# If the previous entry in the map isn't the same object we just found, raise.
|
172
|
-
raise("Duplicate type definition found for name '#{type_defn.name}' at '#{context_description}' (#{prev_type.metadata[:type_class] || prev_type}, #{type_defn.metadata[:type_class] || type_defn})")
|
173
|
-
end
|
174
|
-
when Class
|
175
|
-
if member.respond_to?(:graphql_definition)
|
176
|
-
graphql_member = member.graphql_definition
|
177
|
-
visit(schema, graphql_member, context_description)
|
178
|
-
else
|
179
|
-
raise GraphQL::Schema::InvalidTypeError.new("Unexpected traversal member: #{member} (#{member.class.name})")
|
180
|
-
end
|
181
|
-
else
|
182
|
-
message = "Unexpected schema traversal member: #{member} (#{member.class.name})"
|
183
|
-
raise GraphQL::Schema::InvalidTypeError.new(message)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def visit_fields(schema, type_defn)
|
188
|
-
type_defn.all_fields.each do |field_defn|
|
189
|
-
visit_field_on_type(schema, type_defn, field_defn)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def visit_field_on_type(schema, type_defn, field_defn, dynamic_field: false)
|
194
|
-
base_return_type = field_defn.type.unwrap
|
195
|
-
if base_return_type.is_a?(GraphQL::Schema::LateBoundType)
|
196
|
-
@late_bound_fields << [type_defn, field_defn, dynamic_field]
|
197
|
-
return
|
198
|
-
end
|
199
|
-
if dynamic_field
|
200
|
-
# Don't apply instrumentation to dynamic fields since they're shared constants
|
201
|
-
instrumented_field_defn = field_defn
|
202
|
-
else
|
203
|
-
instrumented_field_defn = @field_instrumenters.reduce(field_defn) do |defn, inst|
|
204
|
-
inst.instrument(type_defn, defn)
|
205
|
-
end
|
206
|
-
@instrumented_field_map[type_defn.name][instrumented_field_defn.name] = instrumented_field_defn
|
207
|
-
end
|
208
|
-
@type_reference_map[instrumented_field_defn.type.unwrap.name] << instrumented_field_defn
|
209
|
-
visit(schema, instrumented_field_defn.type, "Field #{type_defn.name}.#{instrumented_field_defn.name}'s return type")
|
210
|
-
instrumented_field_defn.arguments.each do |name, arg|
|
211
|
-
@type_reference_map[arg.type.unwrap.to_s] << arg
|
212
|
-
visit(schema, arg.type, "Argument #{name} on #{type_defn.name}.#{instrumented_field_defn.name}")
|
213
|
-
end
|
214
|
-
|
215
|
-
# Construct arguments class here, which is later used to generate GraphQL::Query::Arguments
|
216
|
-
# to be passed to a resolver proc
|
217
|
-
GraphQL::Query::Arguments.construct_arguments_class(instrumented_field_defn)
|
218
|
-
end
|
219
|
-
|
220
|
-
def validate_type(member, context_description)
|
221
|
-
error_message = GraphQL::Schema::Validation.validate(member)
|
222
|
-
if error_message
|
223
|
-
raise GraphQL::Schema::InvalidTypeError.new("#{context_description} is invalid: #{error_message}")
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
@@ -1,303 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# This module provides a function for validating GraphQL types.
|
5
|
-
#
|
6
|
-
# Its {RULES} contain objects that respond to `#call(type)`. Rules are
|
7
|
-
# looked up for given types (by class ancestry), then applied to
|
8
|
-
# the object until an error is returned.
|
9
|
-
class Validation
|
10
|
-
# Lookup the rules for `object` based on its class,
|
11
|
-
# Then returns an error message or `nil`
|
12
|
-
# @param object [Object] something to be validated
|
13
|
-
# @return [String, Nil] error message, if there was one
|
14
|
-
def self.validate(object)
|
15
|
-
RULES.each do |parent_class, validations|
|
16
|
-
if object.is_a?(parent_class)
|
17
|
-
validations.each do |rule|
|
18
|
-
if error = rule.call(object)
|
19
|
-
return error
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
|
27
|
-
module Rules
|
28
|
-
# @param property_name [Symbol] The method to validate
|
29
|
-
# @param allowed_classes [Class] Classes which the return value may be an instance of
|
30
|
-
# @return [Proc] A proc which will validate the input by calling `property_name` and asserting it is an instance of one of `allowed_classes`
|
31
|
-
def self.assert_property(property_name, *allowed_classes)
|
32
|
-
# Hide LateBoundType from user-facing errors
|
33
|
-
allowed_classes_message = allowed_classes.map(&:name).reject {|n| n.include?("LateBoundType") }.join(" or ")
|
34
|
-
->(obj) {
|
35
|
-
property_value = obj.public_send(property_name)
|
36
|
-
is_valid_value = allowed_classes.any? { |allowed_class| property_value.is_a?(allowed_class) }
|
37
|
-
is_valid_value ? nil : "#{property_name} must return #{allowed_classes_message}, not #{property_value.class.name} (#{property_value.inspect})"
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
# @param property_name [Symbol] The method whose return value will be validated
|
42
|
-
# @param from_class [Class] The class for keys in the return value
|
43
|
-
# @param to_class [Class] The class for values in the return value
|
44
|
-
# @return [Proc] A proc to validate that validates the input by calling `property_name` and asserting that the return value is a Hash of `{from_class => to_class}` pairs
|
45
|
-
def self.assert_property_mapping(property_name, from_class, to_class)
|
46
|
-
->(obj) {
|
47
|
-
property_value = obj.public_send(property_name)
|
48
|
-
if !property_value.is_a?(Hash)
|
49
|
-
"#{property_name} must be a hash of {#{from_class.name} => #{to_class.name}}, not a #{property_value.class.name} (#{property_value.inspect})"
|
50
|
-
else
|
51
|
-
invalid_key, invalid_value = property_value.find { |key, value| !key.is_a?(from_class) || !value.is_a?(to_class) }
|
52
|
-
if invalid_key
|
53
|
-
"#{property_name} must map #{from_class} => #{to_class}, not #{invalid_key.class.name} => #{invalid_value.class.name} (#{invalid_key.inspect} => #{invalid_value.inspect})"
|
54
|
-
else
|
55
|
-
nil # OK
|
56
|
-
end
|
57
|
-
end
|
58
|
-
}
|
59
|
-
end
|
60
|
-
|
61
|
-
# @param property_name [Symbol] The method whose return value will be validated
|
62
|
-
# @param list_member_class [Class] The class which each member of the returned array should be an instance of
|
63
|
-
# @return [Proc] A proc to validate the input by calling `property_name` and asserting that the return is an Array of `list_member_class` instances
|
64
|
-
def self.assert_property_list_of(property_name, list_member_class)
|
65
|
-
->(obj) {
|
66
|
-
property_value = obj.public_send(property_name)
|
67
|
-
if !property_value.is_a?(Array)
|
68
|
-
"#{property_name} must be an Array of #{list_member_class.name}, not a #{property_value.class.name} (#{property_value.inspect})"
|
69
|
-
else
|
70
|
-
invalid_member = property_value.find { |value| !value.is_a?(list_member_class) }
|
71
|
-
if invalid_member
|
72
|
-
"#{property_name} must contain #{list_member_class.name}, not #{invalid_member.class.name} (#{invalid_member.inspect})"
|
73
|
-
else
|
74
|
-
nil # OK
|
75
|
-
end
|
76
|
-
end
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.count_at_least(item_name, minimum_count, get_items_proc)
|
81
|
-
->(type) {
|
82
|
-
items = get_items_proc.call(type)
|
83
|
-
|
84
|
-
if items.size < minimum_count
|
85
|
-
"#{type.name} must define at least #{minimum_count} #{item_name}. #{items.size} defined."
|
86
|
-
else
|
87
|
-
nil
|
88
|
-
end
|
89
|
-
}
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.assert_named_items_are_valid(item_name, get_items_proc)
|
93
|
-
->(type) {
|
94
|
-
items = get_items_proc.call(type)
|
95
|
-
error_message = nil
|
96
|
-
items.each do |item|
|
97
|
-
item_message = GraphQL::Schema::Validation.validate(item)
|
98
|
-
if item_message
|
99
|
-
error_message = "#{item_name} #{item.name.inspect} #{item_message}"
|
100
|
-
break
|
101
|
-
end
|
102
|
-
end
|
103
|
-
error_message
|
104
|
-
}
|
105
|
-
end
|
106
|
-
|
107
|
-
HAS_AT_LEAST_ONE_FIELD = Rules.count_at_least("field", 1, ->(type) { type.all_fields })
|
108
|
-
FIELDS_ARE_VALID = Rules.assert_named_items_are_valid("field", ->(type) { type.all_fields })
|
109
|
-
HAS_AT_LEAST_ONE_ARGUMENT = Rules.count_at_least("argument", 1, ->(type) { type.arguments })
|
110
|
-
|
111
|
-
HAS_ONE_OR_MORE_POSSIBLE_TYPES = ->(type) {
|
112
|
-
type.possible_types.length >= 1 ? nil : "must have at least one possible type"
|
113
|
-
}
|
114
|
-
|
115
|
-
NAME_IS_STRING = Rules.assert_property(:name, String)
|
116
|
-
DESCRIPTION_IS_STRING_OR_NIL = Rules.assert_property(:description, String, NilClass)
|
117
|
-
ARGUMENTS_ARE_STRING_TO_ARGUMENT = Rules.assert_property_mapping(:arguments, String, GraphQL::Argument)
|
118
|
-
ARGUMENTS_ARE_VALID = Rules.assert_named_items_are_valid("argument", ->(type) { type.arguments.values })
|
119
|
-
|
120
|
-
DEFAULT_VALUE_IS_VALID_FOR_TYPE = ->(type) {
|
121
|
-
if !type.default_value.nil?
|
122
|
-
coerced_value = begin
|
123
|
-
type.type.coerce_isolated_result(type.default_value)
|
124
|
-
rescue => ex
|
125
|
-
ex
|
126
|
-
end
|
127
|
-
|
128
|
-
if coerced_value.nil? || coerced_value.is_a?(StandardError)
|
129
|
-
msg = "default value #{type.default_value.inspect} is not valid for type #{type.type}"
|
130
|
-
msg += " (#{coerced_value})" if coerced_value.is_a?(StandardError)
|
131
|
-
msg
|
132
|
-
end
|
133
|
-
end
|
134
|
-
}
|
135
|
-
|
136
|
-
TYPE_IS_VALID_INPUT_TYPE = ->(type) {
|
137
|
-
outer_type = type.type
|
138
|
-
inner_type = outer_type.is_a?(GraphQL::BaseType) ? outer_type.unwrap : nil
|
139
|
-
|
140
|
-
case inner_type
|
141
|
-
when GraphQL::ScalarType, GraphQL::InputObjectType, GraphQL::EnumType
|
142
|
-
# OK
|
143
|
-
else
|
144
|
-
"type must be a valid input type (Scalar or InputObject), not #{outer_type.class} (#{outer_type})"
|
145
|
-
end
|
146
|
-
}
|
147
|
-
|
148
|
-
SCHEMA_CAN_RESOLVE_TYPES = ->(schema) {
|
149
|
-
if schema.types.values.any? { |type| type.kind.abstract? } && schema.resolve_type_proc.nil?
|
150
|
-
"schema contains Interfaces or Unions, so you must define a `resolve_type -> (obj, ctx) { ... }` function"
|
151
|
-
else
|
152
|
-
# :+1:
|
153
|
-
end
|
154
|
-
}
|
155
|
-
|
156
|
-
SCHEMA_CAN_FETCH_IDS = ->(schema) {
|
157
|
-
has_node_field = schema.query && schema.query.all_fields.any?(&:relay_node_field)
|
158
|
-
if has_node_field && schema.object_from_id_proc.nil?
|
159
|
-
"schema contains `node(id:...)` field, so you must define a `object_from_id -> (id, ctx) { ... }` function"
|
160
|
-
else
|
161
|
-
# :rocket:
|
162
|
-
end
|
163
|
-
}
|
164
|
-
|
165
|
-
SCHEMA_CAN_GENERATE_IDS = ->(schema) {
|
166
|
-
has_id_field = schema.types.values.any? { |t| t.kind.fields? && t.all_fields.any? { |f| f.resolve_proc.is_a?(GraphQL::Relay::GlobalIdResolve) } }
|
167
|
-
if has_id_field && schema.id_from_object_proc.nil?
|
168
|
-
"schema contains `global_id_field`, so you must define a `id_from_object -> (obj, type, ctx) { ... }` function"
|
169
|
-
else
|
170
|
-
# :ok_hand:
|
171
|
-
end
|
172
|
-
}
|
173
|
-
|
174
|
-
SCHEMA_INSTRUMENTERS_ARE_VALID = ->(schema) {
|
175
|
-
errs = []
|
176
|
-
schema.instrumenters[:query].each do |inst|
|
177
|
-
if !inst.respond_to?(:before_query) || !inst.respond_to?(:after_query)
|
178
|
-
errs << "`instrument(:query, #{inst})` is invalid: must respond to `before_query(query)` and `after_query(query)` "
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
schema.instrumenters[:field].each do |inst|
|
183
|
-
if !inst.respond_to?(:instrument)
|
184
|
-
errs << "`instrument(:field, #{inst})` is invalid: must respond to `instrument(type, field)`"
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
if errs.any?
|
189
|
-
errs.join("Invalid instrumenters:\n" + errs.join("\n"))
|
190
|
-
else
|
191
|
-
nil
|
192
|
-
end
|
193
|
-
}
|
194
|
-
|
195
|
-
RESERVED_TYPE_NAME = ->(type) {
|
196
|
-
if type.name.start_with?('__') && !type.introspection?
|
197
|
-
# TODO: make this a hard failure in a later version
|
198
|
-
warn("Name #{type.name.inspect} must not begin with \"__\", which is reserved by GraphQL introspection.")
|
199
|
-
nil
|
200
|
-
else
|
201
|
-
# ok name
|
202
|
-
end
|
203
|
-
}
|
204
|
-
|
205
|
-
RESERVED_NAME = ->(named_thing) {
|
206
|
-
if named_thing.name.start_with?('__')
|
207
|
-
# TODO: make this a hard failure in a later version
|
208
|
-
warn("Name #{named_thing.name.inspect} must not begin with \"__\", which is reserved by GraphQL introspection.")
|
209
|
-
nil
|
210
|
-
else
|
211
|
-
# no worries
|
212
|
-
end
|
213
|
-
}
|
214
|
-
|
215
|
-
INTERFACES_ARE_IMPLEMENTED = ->(obj_type) {
|
216
|
-
field_errors = []
|
217
|
-
obj_type.interfaces.each do |interface_type|
|
218
|
-
interface_type.fields.each do |field_name, field_defn|
|
219
|
-
object_field = obj_type.get_field(field_name)
|
220
|
-
if object_field.nil?
|
221
|
-
field_errors << %|"#{field_name}" is required by #{interface_type.name} but not implemented by #{obj_type.name}|
|
222
|
-
elsif !GraphQL::Execution::Typecast.subtype?(field_defn.type, object_field.type)
|
223
|
-
field_errors << %|"#{field_name}" is required by #{interface_type.name} to return #{field_defn.type} but #{obj_type.name}.#{field_name} returns #{object_field.type}|
|
224
|
-
else
|
225
|
-
field_defn.arguments.each do |arg_name, arg_defn|
|
226
|
-
object_field_arg = object_field.arguments[arg_name]
|
227
|
-
if object_field_arg.nil?
|
228
|
-
field_errors << %|"#{arg_name}" argument is required by #{interface_type.name}.#{field_name} but not accepted by #{obj_type.name}.#{field_name}|
|
229
|
-
elsif arg_defn.type != object_field_arg.type
|
230
|
-
field_errors << %|"#{arg_name}" is required by #{interface_type.name}.#{field_defn.name} to accept #{arg_defn.type} but #{obj_type.name}.#{field_name} accepts #{object_field_arg.type} for "#{arg_name}"|
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
object_field.arguments.each do |arg_name, arg_defn|
|
235
|
-
if field_defn.arguments[arg_name].nil? && arg_defn.type.is_a?(GraphQL::NonNullType)
|
236
|
-
field_errors << %|"#{arg_name}" is not accepted by #{interface_type.name}.#{field_name} but required by #{obj_type.name}.#{field_name}|
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
if field_errors.any?
|
243
|
-
"#{obj_type.name} failed to implement some interfaces: #{field_errors.join(", ")}"
|
244
|
-
else
|
245
|
-
nil
|
246
|
-
end
|
247
|
-
}
|
248
|
-
end
|
249
|
-
|
250
|
-
# A mapping of `{Class => [Proc, Proc...]}` pairs.
|
251
|
-
# To validate an instance, find entries where `object.is_a?(key)` is true.
|
252
|
-
# Then apply each rule from the matching values.
|
253
|
-
RULES = {
|
254
|
-
GraphQL::Field => [
|
255
|
-
Rules::NAME_IS_STRING,
|
256
|
-
Rules::RESERVED_NAME,
|
257
|
-
Rules::DESCRIPTION_IS_STRING_OR_NIL,
|
258
|
-
Rules.assert_property(:deprecation_reason, String, NilClass),
|
259
|
-
Rules.assert_property(:type, GraphQL::BaseType, GraphQL::Schema::LateBoundType),
|
260
|
-
Rules.assert_property(:property, Symbol, NilClass),
|
261
|
-
Rules::ARGUMENTS_ARE_STRING_TO_ARGUMENT,
|
262
|
-
Rules::ARGUMENTS_ARE_VALID,
|
263
|
-
],
|
264
|
-
GraphQL::Argument => [
|
265
|
-
Rules::NAME_IS_STRING,
|
266
|
-
Rules::RESERVED_NAME,
|
267
|
-
Rules::DESCRIPTION_IS_STRING_OR_NIL,
|
268
|
-
Rules::TYPE_IS_VALID_INPUT_TYPE,
|
269
|
-
Rules::DEFAULT_VALUE_IS_VALID_FOR_TYPE,
|
270
|
-
],
|
271
|
-
GraphQL::BaseType => [
|
272
|
-
Rules::NAME_IS_STRING,
|
273
|
-
Rules::RESERVED_TYPE_NAME,
|
274
|
-
Rules::DESCRIPTION_IS_STRING_OR_NIL,
|
275
|
-
],
|
276
|
-
GraphQL::ObjectType => [
|
277
|
-
Rules::HAS_AT_LEAST_ONE_FIELD,
|
278
|
-
Rules.assert_property_list_of(:interfaces, GraphQL::InterfaceType),
|
279
|
-
Rules::FIELDS_ARE_VALID,
|
280
|
-
Rules::INTERFACES_ARE_IMPLEMENTED,
|
281
|
-
],
|
282
|
-
GraphQL::InputObjectType => [
|
283
|
-
Rules::HAS_AT_LEAST_ONE_ARGUMENT,
|
284
|
-
Rules::ARGUMENTS_ARE_STRING_TO_ARGUMENT,
|
285
|
-
Rules::ARGUMENTS_ARE_VALID,
|
286
|
-
],
|
287
|
-
GraphQL::UnionType => [
|
288
|
-
Rules.assert_property_list_of(:possible_types, GraphQL::ObjectType),
|
289
|
-
Rules::HAS_ONE_OR_MORE_POSSIBLE_TYPES,
|
290
|
-
],
|
291
|
-
GraphQL::InterfaceType => [
|
292
|
-
Rules::FIELDS_ARE_VALID,
|
293
|
-
],
|
294
|
-
GraphQL::Schema => [
|
295
|
-
Rules::SCHEMA_INSTRUMENTERS_ARE_VALID,
|
296
|
-
Rules::SCHEMA_CAN_RESOLVE_TYPES,
|
297
|
-
Rules::SCHEMA_CAN_FETCH_IDS,
|
298
|
-
Rules::SCHEMA_CAN_GENERATE_IDS,
|
299
|
-
],
|
300
|
-
}
|
301
|
-
end
|
302
|
-
end
|
303
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module StaticValidation
|
4
|
-
class DefaultVisitor < BaseVisitor
|
5
|
-
include(GraphQL::StaticValidation::DefinitionDependencies)
|
6
|
-
|
7
|
-
StaticValidation::ALL_RULES.reverse_each do |r|
|
8
|
-
include(r)
|
9
|
-
end
|
10
|
-
|
11
|
-
include(GraphQL::InternalRepresentation::Rewrite)
|
12
|
-
include(ContextMethods)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module StaticValidation
|
4
|
-
class NoValidateVisitor < StaticValidation::BaseVisitor
|
5
|
-
include(GraphQL::InternalRepresentation::Rewrite)
|
6
|
-
include(GraphQL::StaticValidation::DefinitionDependencies)
|
7
|
-
include(ContextMethods)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
data/lib/graphql/string_type.rb
DELETED