graphql 1.10.2 → 2.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +45 -8
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +49 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +24 -33
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +30 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +125 -117
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +52 -36
- data/lib/graphql/analysis/ast.rb +7 -8
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +31 -18
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +26 -18
- data/lib/graphql/dataloader/null_dataloader.rb +24 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +164 -0
- data/lib/graphql/dataloader.rb +311 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +77 -44
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +104 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +62 -24
- data/lib/graphql/execution/interpreter/runtime.rb +826 -464
- data/lib/graphql/execution/interpreter.rb +206 -68
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +55 -136
- data/lib/graphql/execution/multiplex.rb +6 -162
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +7 -2
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +11 -5
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +4 -17
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +11 -6
- data/lib/graphql/introspection/type_type.rb +31 -14
- data/lib/graphql/introspection.rb +100 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +96 -44
- data/lib/graphql/language/lexer.rb +216 -1462
- data/lib/graphql/language/nodes.rb +126 -129
- data/lib/graphql/language/parser.rb +997 -933
- data/lib/graphql/language/parser.y +148 -118
- data/lib/graphql/language/printer.rb +48 -23
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +192 -84
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +45 -3
- data/lib/graphql/pagination/array_connection.rb +6 -4
- data/lib/graphql/pagination/connection.rb +105 -23
- data/lib/graphql/pagination/connections.rb +62 -35
- data/lib/graphql/pagination/relation_connection.rb +88 -36
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +203 -198
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +33 -7
- data/lib/graphql/query/null_context.rb +22 -9
- data/lib/graphql/query/validation_pipeline.rb +16 -38
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +36 -12
- data/lib/graphql/query.rb +92 -44
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +41 -10
- data/lib/graphql/relay/range_add.rb +17 -10
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/schema/addition.rb +245 -0
- data/lib/graphql/schema/argument.rb +250 -46
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +243 -89
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +108 -20
- data/lib/graphql/schema/enum.rb +105 -44
- data/lib/graphql/schema/enum_value.rb +15 -25
- data/lib/graphql/schema/field/connection_extension.rb +50 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +476 -331
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +6 -8
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +133 -121
- data/lib/graphql/schema/interface.rb +17 -45
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +25 -8
- data/lib/graphql/schema/loader.rb +139 -103
- data/lib/graphql/schema/member/base_dsl_methods.rb +29 -35
- data/lib/graphql/schema/member/build_type.rb +19 -14
- data/lib/graphql/schema/member/has_arguments.rb +310 -26
- data/lib/graphql/schema/member/has_ast_node.rb +16 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
- data/lib/graphql/schema/member/has_directives.rb +118 -0
- data/lib/graphql/schema/member/has_fields.rb +164 -42
- data/lib/graphql/schema/member/has_interfaces.rb +129 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +57 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +12 -7
- data/lib/graphql/schema/object.rb +35 -69
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
- data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
- data/lib/graphql/schema/resolver.rb +144 -79
- data/lib/graphql/schema/scalar.rb +27 -18
- data/lib/graphql/schema/subscription.rb +55 -26
- data/lib/graphql/schema/timeout.rb +45 -35
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +21 -4
- data/lib/graphql/schema/union.rb +48 -13
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +185 -32
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +471 -1116
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +13 -27
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +69 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +92 -49
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +32 -20
- data/lib/graphql/static_validation.rb +1 -2
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +126 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +81 -35
- data/lib/graphql/subscriptions/instrumentation.rb +0 -52
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +113 -58
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +26 -2
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +64 -43
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +23 -71
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +20 -9
- data/lib/graphql/types/iso_8601_date_time.rb +36 -10
- data/lib/graphql/types/relay/base_connection.rb +18 -92
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +75 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +25 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
- data/lib/graphql/types/relay.rb +10 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +54 -65
- data/readme.md +3 -6
- metadata +116 -236
- data/lib/graphql/analysis/analyze_query.rb +0 -91
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -230
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -435
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -210
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -42
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -127
- data/lib/graphql/execution/execute.rb +0 -326
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -222
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -124
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -132
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -65
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -258
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -121
- data/lib/graphql/query/arguments.rb +0 -188
- data/lib/graphql/query/arguments_cache.rb +0 -25
- data/lib/graphql/query/executor.rb +0 -53
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -39
- data/lib/graphql/relay/array_connection.rb +0 -85
- data/lib/graphql/relay/base_connection.rb +0 -176
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -41
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -105
- data/lib/graphql/relay/node.rb +0 -36
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -76
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -15
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
- data/lib/graphql/schema/member/instrumentation.rb +0 -132
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -39
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -86
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -303
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -65
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
- data/lib/graphql/types/relay/node_field.rb +0 -43
- data/lib/graphql/types/relay/nodes_field.rb +0 -45
- data/lib/graphql/union_type.rb +0 -113
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -1,132 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# test_via: ../object.rb
|
3
|
-
|
4
|
-
module GraphQL
|
5
|
-
class Schema
|
6
|
-
class Member
|
7
|
-
module Instrumentation
|
8
|
-
module_function
|
9
|
-
def instrument(type, field)
|
10
|
-
return_type = field.type.unwrap
|
11
|
-
if (return_type.is_a?(GraphQL::ObjectType) && return_type.metadata[:type_class]) ||
|
12
|
-
return_type.is_a?(GraphQL::InterfaceType) ||
|
13
|
-
(return_type.is_a?(GraphQL::UnionType) && return_type.possible_types.any? { |t| t.metadata[:type_class] })
|
14
|
-
field = apply_proxy(field)
|
15
|
-
end
|
16
|
-
|
17
|
-
field
|
18
|
-
end
|
19
|
-
|
20
|
-
def before_query(query)
|
21
|
-
# Get the root type for this query
|
22
|
-
root_node = query.irep_selection
|
23
|
-
if root_node.nil?
|
24
|
-
# It's an invalid query, nothing to do here
|
25
|
-
else
|
26
|
-
root_type = query.irep_selection.return_type
|
27
|
-
# If it has a wrapper, apply it
|
28
|
-
wrapper_class = root_type.metadata[:type_class]
|
29
|
-
if wrapper_class
|
30
|
-
new_root_value = wrapper_class.authorized_new(query.root_value, query.context)
|
31
|
-
new_root_value = query.schema.sync_lazy(new_root_value)
|
32
|
-
if new_root_value.nil?
|
33
|
-
# This is definitely a hack,
|
34
|
-
# but we need some way to tell execute.rb not to run.
|
35
|
-
query.context[:__root_unauthorized] = true
|
36
|
-
end
|
37
|
-
query.root_value = new_root_value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def after_query(_query)
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
module_function
|
48
|
-
|
49
|
-
def apply_proxy(field)
|
50
|
-
resolve_proc = field.resolve_proc
|
51
|
-
lazy_resolve_proc = field.lazy_resolve_proc
|
52
|
-
inner_return_type = field.type.unwrap
|
53
|
-
depth = list_depth(field.type)
|
54
|
-
|
55
|
-
field.redefine(
|
56
|
-
resolve: ProxiedResolve.new(inner_resolve: resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
|
57
|
-
lazy_resolve: ProxiedResolve.new(inner_resolve: lazy_resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
def list_depth(type, starting_at = 0)
|
62
|
-
case type
|
63
|
-
when GraphQL::ListType
|
64
|
-
list_depth(type.of_type, starting_at + 1)
|
65
|
-
when GraphQL::NonNullType
|
66
|
-
list_depth(type.of_type, starting_at)
|
67
|
-
else
|
68
|
-
starting_at
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
class ProxiedResolve
|
73
|
-
def initialize(inner_resolve:, list_depth:, inner_return_type:)
|
74
|
-
@inner_resolve = inner_resolve
|
75
|
-
@inner_return_type = inner_return_type
|
76
|
-
@list_depth = list_depth
|
77
|
-
end
|
78
|
-
|
79
|
-
def call(obj, args, ctx)
|
80
|
-
result = @inner_resolve.call(obj, args, ctx)
|
81
|
-
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? || execution_errors?(result) || ctx.wrapped_object
|
82
|
-
result
|
83
|
-
else
|
84
|
-
ctx.wrapped_object = true
|
85
|
-
proxy_to_depth(result, @list_depth, ctx)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def execution_errors?(result)
|
92
|
-
result.is_a?(GraphQL::ExecutionError) ||
|
93
|
-
(result.is_a?(Array) && result.any? && result.all? { |v| v.is_a?(GraphQL::ExecutionError) })
|
94
|
-
end
|
95
|
-
|
96
|
-
def proxy_to_depth(inner_obj, depth, ctx)
|
97
|
-
if depth > 0
|
98
|
-
inner_obj.map { |i| proxy_to_depth(i, depth - 1, ctx) }
|
99
|
-
else
|
100
|
-
ctx.schema.after_lazy(inner_obj) do |inner_obj|
|
101
|
-
if inner_obj.nil?
|
102
|
-
# For lists with nil, we need another nil check here
|
103
|
-
nil
|
104
|
-
else
|
105
|
-
concrete_type_or_lazy = case @inner_return_type
|
106
|
-
when GraphQL::UnionType, GraphQL::InterfaceType
|
107
|
-
ctx.query.resolve_type(@inner_return_type, inner_obj)
|
108
|
-
when GraphQL::ObjectType
|
109
|
-
@inner_return_type
|
110
|
-
else
|
111
|
-
raise "unexpected proxying type #{@inner_return_type} for #{inner_obj} at #{ctx.owner_type}.#{ctx.field.name}"
|
112
|
-
end
|
113
|
-
|
114
|
-
# .resolve_type may have returned a lazy
|
115
|
-
ctx.schema.after_lazy(concrete_type_or_lazy) do |concrete_type|
|
116
|
-
if concrete_type && (object_class = concrete_type.metadata[:type_class])
|
117
|
-
# use the query-level context here, since it won't be field-specific anyways
|
118
|
-
query_ctx = ctx.query.context
|
119
|
-
object_class.authorized_new(inner_obj, query_ctx)
|
120
|
-
else
|
121
|
-
inner_obj
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# Given {steps} and {arguments}, call steps in order, passing `(*arguments, next_step)`.
|
5
|
-
#
|
6
|
-
# Steps should call `next_step.call` to continue the chain, or _not_ call it to stop the chain.
|
7
|
-
class MiddlewareChain
|
8
|
-
extend Forwardable
|
9
|
-
|
10
|
-
# @return [Array<#call(*args)>] Steps in this chain, will be called with arguments and `next_middleware`
|
11
|
-
attr_reader :steps, :final_step
|
12
|
-
|
13
|
-
def initialize(steps: [], final_step: nil)
|
14
|
-
@steps = steps
|
15
|
-
@final_step = final_step
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize_copy(other)
|
19
|
-
super
|
20
|
-
@steps = other.steps.dup
|
21
|
-
end
|
22
|
-
|
23
|
-
def_delegators :@steps, :[], :first, :insert, :delete
|
24
|
-
|
25
|
-
def <<(callable)
|
26
|
-
add_middleware(callable)
|
27
|
-
end
|
28
|
-
|
29
|
-
def push(callable)
|
30
|
-
add_middleware(callable)
|
31
|
-
end
|
32
|
-
|
33
|
-
def ==(other)
|
34
|
-
steps == other.steps && final_step == other.final_step
|
35
|
-
end
|
36
|
-
|
37
|
-
def invoke(arguments)
|
38
|
-
invoke_core(0, arguments)
|
39
|
-
end
|
40
|
-
|
41
|
-
def concat(callables)
|
42
|
-
callables.each { |c| add_middleware(c) }
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def invoke_core(index, arguments)
|
48
|
-
if index >= steps.length
|
49
|
-
final_step.call(*arguments)
|
50
|
-
else
|
51
|
-
steps[index].call(*arguments) { |next_args = arguments| invoke_core(index + 1, next_args) }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def add_middleware(callable)
|
56
|
-
# TODO: Stop wrapping callables once deprecated middleware becomes unsupported
|
57
|
-
steps << wrap(callable)
|
58
|
-
end
|
59
|
-
|
60
|
-
# TODO: Remove this code once deprecated middleware becomes unsupported
|
61
|
-
class MiddlewareWrapper
|
62
|
-
attr_reader :callable
|
63
|
-
def initialize(callable)
|
64
|
-
@callable = callable
|
65
|
-
end
|
66
|
-
|
67
|
-
def call(*args, &next_middleware)
|
68
|
-
callable.call(*args, next_middleware)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def wrap(callable)
|
73
|
-
if BackwardsCompatibility.get_arity(callable) == 6
|
74
|
-
warn("Middleware that takes a next_middleware parameter is deprecated (#{callable.inspect}); instead, accept a block and use yield.")
|
75
|
-
MiddlewareWrapper.new(callable)
|
76
|
-
else
|
77
|
-
callable
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# Find the members of a union or interface within a given schema.
|
5
|
-
#
|
6
|
-
# (Although its members never change, unions are handled this way to simplify execution code.)
|
7
|
-
#
|
8
|
-
# Internally, the calculation is cached. It's assumed that schema members _don't_ change after creating the schema!
|
9
|
-
#
|
10
|
-
# @example Get an interface's possible types
|
11
|
-
# possible_types = GraphQL::Schema::PossibleTypes(MySchema)
|
12
|
-
# possible_types.possible_types(MyInterface)
|
13
|
-
# # => [MyObjectType, MyOtherObjectType]
|
14
|
-
class PossibleTypes
|
15
|
-
def initialize(schema)
|
16
|
-
@object_types = schema.types.values.select { |type| type.kind.object? }
|
17
|
-
|
18
|
-
@interface_implementers = Hash.new do |hash, key|
|
19
|
-
hash[key] = @object_types.select { |type| type.interfaces.include?(key) }.sort_by(&:name)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def possible_types(type_defn, ctx)
|
24
|
-
case type_defn
|
25
|
-
when Module
|
26
|
-
possible_types(type_defn.graphql_definition, ctx)
|
27
|
-
when GraphQL::UnionType
|
28
|
-
type_defn.possible_types(ctx)
|
29
|
-
when GraphQL::InterfaceType
|
30
|
-
@interface_implementers[type_defn]
|
31
|
-
when GraphQL::BaseType
|
32
|
-
[type_defn]
|
33
|
-
else
|
34
|
-
raise "Unexpected possible_types object: #{type_defn.inspect}"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# - Store a table of errors & handlers
|
5
|
-
# - Rescue errors in a middleware chain, then check for a handler
|
6
|
-
# - If a handler is found, use it & return a {GraphQL::ExecutionError}
|
7
|
-
# - If no handler is found, re-raise the error
|
8
|
-
class RescueMiddleware
|
9
|
-
# @return [Hash] `{class => proc}` pairs for handling errors
|
10
|
-
attr_reader :rescue_table
|
11
|
-
def initialize
|
12
|
-
@rescue_table = {}
|
13
|
-
end
|
14
|
-
|
15
|
-
# @example Rescue from not-found by telling the user
|
16
|
-
# MySchema.rescue_from(ActiveRecord::RecordNotFound) { "An item could not be found" }
|
17
|
-
#
|
18
|
-
# @param error_classes [Class] one or more classes of errors to rescue from
|
19
|
-
# @yield [err] A handler to return a message for these error instances
|
20
|
-
# @yieldparam [Exception] an error that was rescued
|
21
|
-
# @yieldreturn [String] message to put in GraphQL response
|
22
|
-
def rescue_from(*error_classes, &block)
|
23
|
-
error_classes.map{ |error_class| rescue_table[error_class] = block }
|
24
|
-
end
|
25
|
-
|
26
|
-
# Remove the handler for `error_classs`
|
27
|
-
# @param error_class [Class] the error class whose handler should be removed
|
28
|
-
def remove_handler(*error_classes)
|
29
|
-
error_classes.map{ |error_class| rescue_table.delete(error_class) }
|
30
|
-
end
|
31
|
-
|
32
|
-
# Implement the requirement for {GraphQL::Schema::MiddlewareChain}
|
33
|
-
def call(*args)
|
34
|
-
begin
|
35
|
-
yield
|
36
|
-
rescue StandardError => err
|
37
|
-
attempt_rescue(err)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def attempt_rescue(err)
|
44
|
-
rescue_table.each { |klass, handler|
|
45
|
-
if klass.is_a?(Class) && err.is_a?(klass) && handler
|
46
|
-
result = handler.call(err)
|
47
|
-
case result
|
48
|
-
when String
|
49
|
-
return GraphQL::ExecutionError.new(result)
|
50
|
-
when GraphQL::ExecutionError
|
51
|
-
return result
|
52
|
-
end
|
53
|
-
end
|
54
|
-
}
|
55
|
-
|
56
|
-
raise(err)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -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.types.values
|
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
|