graphql 2.6.12 → 2.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rdoc_options +4 -0
- data/lib/generators/graphql/core.rb +1 -0
- data/lib/generators/graphql/detailed_trace_generator.rb +1 -0
- data/lib/generators/graphql/enum_generator.rb +1 -0
- data/lib/generators/graphql/field_extractor.rb +1 -0
- data/lib/generators/graphql/input_generator.rb +1 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +1 -0
- data/lib/generators/graphql/install_generator.rb +1 -0
- data/lib/generators/graphql/interface_generator.rb +1 -0
- data/lib/generators/graphql/loader_generator.rb +8 -2
- data/lib/generators/graphql/mutation_create_generator.rb +8 -2
- data/lib/generators/graphql/mutation_delete_generator.rb +8 -2
- data/lib/generators/graphql/mutation_generator.rb +8 -2
- data/lib/generators/graphql/mutation_update_generator.rb +8 -2
- data/lib/generators/graphql/object_generator.rb +1 -0
- data/lib/generators/graphql/orm_mutations_base.rb +8 -2
- data/lib/generators/graphql/relay.rb +1 -0
- data/lib/generators/graphql/relay_generator.rb +1 -0
- data/lib/generators/graphql/scalar_generator.rb +1 -0
- data/lib/generators/graphql/type_generator.rb +38 -8
- data/lib/generators/graphql/union_generator.rb +1 -0
- data/lib/graphql/analysis/analyzer.rb +35 -9
- data/lib/graphql/analysis/field_usage.rb +1 -0
- data/lib/graphql/analysis/max_query_complexity.rb +3 -2
- data/lib/graphql/analysis/max_query_depth.rb +1 -0
- data/lib/graphql/analysis/query_complexity.rb +57 -20
- data/lib/graphql/analysis/query_depth.rb +17 -12
- data/lib/graphql/analysis/visitor.rb +79 -16
- data/lib/graphql/analysis.rb +23 -6
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/autoload.rb +30 -7
- data/lib/graphql/backtrace/table.rb +21 -5
- data/lib/graphql/backtrace/traced_error.rb +8 -3
- data/lib/graphql/backtrace.rb +14 -9
- data/lib/graphql/coercion_error.rb +1 -0
- data/lib/graphql/current.rb +44 -19
- data/lib/graphql/dashboard/application_controller.rb +1 -0
- data/lib/graphql/dashboard/detailed_traces.rb +1 -0
- data/lib/graphql/dashboard/installable.rb +1 -0
- data/lib/graphql/dashboard/landings_controller.rb +1 -0
- data/lib/graphql/dashboard/limiters.rb +1 -0
- data/lib/graphql/dashboard/operation_store.rb +1 -0
- data/lib/graphql/dashboard/statics_controller.rb +1 -0
- data/lib/graphql/dashboard/subscriptions.rb +1 -0
- data/lib/graphql/dashboard.rb +36 -22
- data/lib/graphql/dataloader/active_record_association_source.rb +1 -0
- data/lib/graphql/dataloader/active_record_source.rb +1 -0
- data/lib/graphql/dataloader/async_dataloader.rb +8 -7
- data/lib/graphql/dataloader/null_dataloader.rb +4 -3
- data/lib/graphql/dataloader/request.rb +8 -2
- data/lib/graphql/dataloader/request_all.rb +8 -2
- data/lib/graphql/dataloader/source.rb +127 -35
- data/lib/graphql/dataloader.rb +91 -42
- data/lib/graphql/date_encoding_error.rb +2 -1
- data/lib/graphql/dig.rb +12 -3
- data/lib/graphql/duration_encoding_error.rb +2 -1
- data/lib/graphql/execution/directive_checks.rb +8 -3
- data/lib/graphql/execution/errors.rb +20 -6
- data/lib/graphql/execution/field_resolve_step.rb +263 -161
- data/lib/graphql/execution/finalize.rb +12 -6
- data/lib/graphql/execution/input_values.rb +5 -2
- data/lib/graphql/execution/interpreter/argument_value.rb +17 -5
- data/lib/graphql/execution/interpreter/arguments.rb +24 -9
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -1
- data/lib/graphql/execution/interpreter/execution_errors.rb +1 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +1 -0
- data/lib/graphql/execution/interpreter/resolve.rb +18 -8
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +4 -1
- data/lib/graphql/execution/interpreter/runtime.rb +66 -23
- data/lib/graphql/execution/interpreter.rb +15 -6
- data/lib/graphql/execution/lazy/lazy_method_map.rb +21 -8
- data/lib/graphql/execution/lazy.rb +34 -10
- data/lib/graphql/execution/load_argument_step.rb +1 -0
- data/lib/graphql/execution/lookahead.rb +137 -54
- data/lib/graphql/execution/multiplex.rb +4 -4
- data/lib/graphql/execution/next.rb +7 -0
- data/lib/graphql/execution/prepare_object_step.rb +38 -13
- data/lib/graphql/execution/resolve_type_step.rb +2 -1
- data/lib/graphql/execution/runner.rb +9 -3
- data/lib/graphql/execution/selections_step.rb +3 -2
- data/lib/graphql/execution.rb +2 -2
- data/lib/graphql/execution_error.rb +19 -10
- data/lib/graphql/float_decoding_error.rb +1 -0
- data/lib/graphql/float_encoding_error.rb +7 -2
- data/lib/graphql/integer_decoding_error.rb +2 -1
- data/lib/graphql/integer_encoding_error.rb +8 -3
- data/lib/graphql/introspection/base_object.rb +3 -1
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/dynamic_fields.rb +1 -0
- data/lib/graphql/introspection/entry_points.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/input_value_type.rb +1 -0
- data/lib/graphql/introspection/introspection_query.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +1 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/introspection.rb +1 -0
- data/lib/graphql/invalid_name_error.rb +1 -0
- data/lib/graphql/invalid_null_error.rb +19 -6
- data/lib/graphql/language/block_string.rb +2 -1
- data/lib/graphql/language/cache.rb +10 -4
- data/lib/graphql/language/comment.rb +1 -0
- data/lib/graphql/language/definition_slice.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +9 -10
- data/lib/graphql/language/generation.rb +23 -9
- data/lib/graphql/language/lexer.rb +6 -1
- data/lib/graphql/language/nodes.rb +2094 -419
- data/lib/graphql/language/parser.rb +22 -12
- data/lib/graphql/language/printer.rb +31 -16
- data/lib/graphql/language/sanitized_printer.rb +16 -5
- data/lib/graphql/language/static_visitor.rb +19 -4
- data/lib/graphql/language/visitor.rb +51 -29
- data/lib/graphql/language.rb +13 -7
- data/lib/graphql/load_application_object_failed_error.rb +14 -5
- data/lib/graphql/name_validator.rb +1 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +1 -0
- data/lib/graphql/pagination/array_connection.rb +20 -6
- data/lib/graphql/pagination/connection.rb +178 -48
- data/lib/graphql/pagination/connections.rb +21 -14
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -0
- data/lib/graphql/pagination/relation_connection.rb +137 -29
- data/lib/graphql/pagination/sequel_dataset_connection.rb +1 -0
- data/lib/graphql/pagination.rb +1 -0
- data/lib/graphql/parse_error.rb +1 -0
- data/lib/graphql/query/context/scoped_context.rb +2 -1
- data/lib/graphql/query/context.rb +106 -35
- data/lib/graphql/query/fingerprint.rb +15 -7
- data/lib/graphql/query/input_validation_result.rb +1 -0
- data/lib/graphql/query/null_context.rb +1 -0
- data/lib/graphql/query/partial.rb +28 -16
- data/lib/graphql/query/result.rb +15 -5
- data/lib/graphql/query/validation_pipeline.rb +16 -6
- data/lib/graphql/query/variable_validation_error.rb +1 -0
- data/lib/graphql/query/variables.rb +4 -1
- data/lib/graphql/query.rb +193 -49
- data/lib/graphql/railtie.rb +7 -3
- data/lib/graphql/rake_task/validate.rb +72 -17
- data/lib/graphql/rake_task.rb +55 -23
- data/lib/graphql/relay/range_add.rb +32 -21
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +9 -6
- data/lib/graphql/rubocop/graphql/default_required_true.rb +9 -6
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +12 -8
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +9 -5
- data/lib/graphql/rubocop.rb +1 -0
- data/lib/graphql/runtime_error.rb +1 -0
- data/lib/graphql/runtime_type_error.rb +1 -0
- data/lib/graphql/schema/addition.rb +69 -50
- data/lib/graphql/schema/always_visible.rb +1 -0
- data/lib/graphql/schema/argument.rb +279 -45
- data/lib/graphql/schema/base_64_encoder.rb +2 -2
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/build_from_definition.rb +507 -178
- data/lib/graphql/schema/built_in_types.rb +1 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -0
- data/lib/graphql/schema/directive/feature.rb +39 -22
- data/lib/graphql/schema/directive/flagged.rb +6 -1
- data/lib/graphql/schema/directive/include.rb +1 -0
- data/lib/graphql/schema/directive/one_of.rb +1 -0
- data/lib/graphql/schema/directive/skip.rb +1 -0
- data/lib/graphql/schema/directive/specified_by.rb +1 -0
- data/lib/graphql/schema/directive/transform.rb +17 -8
- data/lib/graphql/schema/directive.rb +28 -7
- data/lib/graphql/schema/enum.rb +99 -38
- data/lib/graphql/schema/enum_value.rb +21 -13
- data/lib/graphql/schema/field/connection_extension.rb +10 -2
- data/lib/graphql/schema/field/scope_extension.rb +1 -0
- data/lib/graphql/schema/field.rb +622 -110
- data/lib/graphql/schema/field_extension.rb +89 -34
- data/lib/graphql/schema/find_inherited_value.rb +5 -3
- data/lib/graphql/schema/finder.rb +22 -8
- data/lib/graphql/schema/has_single_input_argument.rb +39 -6
- data/lib/graphql/schema/input_object.rb +40 -13
- data/lib/graphql/schema/interface.rb +33 -17
- data/lib/graphql/schema/introspection_system.rb +7 -3
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +15 -4
- data/lib/graphql/schema/loader.rb +23 -12
- data/lib/graphql/schema/member/base_dsl_methods.rb +58 -12
- data/lib/graphql/schema/member/build_type.rb +21 -7
- data/lib/graphql/schema/member/graphql_type_names.rb +10 -6
- data/lib/graphql/schema/member/has_arguments.rb +111 -48
- data/lib/graphql/schema/member/has_ast_node.rb +1 -0
- data/lib/graphql/schema/member/has_authorization.rb +5 -0
- data/lib/graphql/schema/member/has_dataloader.rb +91 -34
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -2
- data/lib/graphql/schema/member/has_directives.rb +45 -11
- data/lib/graphql/schema/member/has_fields.rb +151 -70
- data/lib/graphql/schema/member/has_interfaces.rb +8 -2
- data/lib/graphql/schema/member/has_path.rb +14 -5
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +1 -0
- data/lib/graphql/schema/member/has_validators.rb +19 -4
- data/lib/graphql/schema/member/relay_shortcuts.rb +10 -2
- data/lib/graphql/schema/member/scoped.rb +14 -3
- data/lib/graphql/schema/member/type_system_helpers.rb +36 -6
- data/lib/graphql/schema/member/validates_input.rb +1 -0
- data/lib/graphql/schema/member.rb +9 -2
- data/lib/graphql/schema/mutation.rb +50 -46
- data/lib/graphql/schema/non_null.rb +21 -5
- data/lib/graphql/schema/object.rb +44 -15
- data/lib/graphql/schema/printer.rb +52 -31
- data/lib/graphql/schema/ractor_shareable.rb +6 -2
- data/lib/graphql/schema/relay_classic_mutation.rb +3 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +29 -7
- data/lib/graphql/schema/resolver.rb +156 -45
- data/lib/graphql/schema/scalar.rb +1 -0
- data/lib/graphql/schema/subscription.rb +67 -28
- data/lib/graphql/schema/timeout.rb +65 -25
- data/lib/graphql/schema/type_expression.rb +14 -5
- data/lib/graphql/schema/type_membership.rb +29 -10
- data/lib/graphql/schema/union.rb +4 -2
- data/lib/graphql/schema/unique_within_type.rb +24 -5
- data/lib/graphql/schema/validator/all_validator.rb +17 -9
- data/lib/graphql/schema/validator/allow_blank_validator.rb +8 -2
- data/lib/graphql/schema/validator/allow_null_validator.rb +8 -2
- data/lib/graphql/schema/validator/exclusion_validator.rb +14 -5
- data/lib/graphql/schema/validator/format_validator.rb +21 -10
- data/lib/graphql/schema/validator/inclusion_validator.rb +15 -6
- data/lib/graphql/schema/validator/length_validator.rb +23 -12
- data/lib/graphql/schema/validator/numericality_validator.rb +29 -16
- data/lib/graphql/schema/validator/required_validator.rb +45 -31
- data/lib/graphql/schema/validator.rb +89 -25
- data/lib/graphql/schema/visibility/migration.rb +14 -7
- data/lib/graphql/schema/visibility/profile.rb +20 -17
- data/lib/graphql/schema/visibility/visit.rb +12 -10
- data/lib/graphql/schema/visibility.rb +24 -20
- data/lib/graphql/schema/warden.rb +117 -31
- data/lib/graphql/schema/wrapper.rb +4 -1
- data/lib/graphql/schema.rb +1050 -302
- data/lib/graphql/static_validation/all_rules.rb +2 -1
- data/lib/graphql/static_validation/base_visitor.rb +48 -8
- data/lib/graphql/static_validation/definition_dependencies.rb +27 -7
- data/lib/graphql/static_validation/error.rb +3 -0
- data/lib/graphql/static_validation/interpreter_visitor.rb +1 -0
- data/lib/graphql/static_validation/literal_validator.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +4 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -0
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +3 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +3 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +9 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +295 -134
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +14 -2
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +1 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +3 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +3 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +1 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +4 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +1 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +3 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +1 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +3 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +4 -1
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +3 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +207 -51
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +3 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -3
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +1 -0
- data/lib/graphql/static_validation/validation_context.rb +3 -2
- data/lib/graphql/static_validation/validation_timeout_error.rb +1 -0
- data/lib/graphql/static_validation/validator.rb +41 -16
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +1 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +85 -65
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +1 -0
- data/lib/graphql/subscriptions/event.rb +25 -6
- data/lib/graphql/subscriptions/serialize.rb +58 -19
- data/lib/graphql/subscriptions.rb +172 -46
- data/lib/graphql/testing/helpers.rb +17 -4
- data/lib/graphql/testing/mock_action_cable.rb +55 -33
- data/lib/graphql/testing.rb +1 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +17 -9
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_trace.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -1
- data/lib/graphql/tracing/appsignal_trace.rb +16 -7
- data/lib/graphql/tracing/appsignal_tracing.rb +7 -3
- data/lib/graphql/tracing/call_legacy_tracers.rb +1 -0
- data/lib/graphql/tracing/data_dog_trace.rb +17 -6
- data/lib/graphql/tracing/data_dog_tracing.rb +10 -3
- data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace.rb +105 -42
- data/lib/graphql/tracing/legacy_hooks_trace.rb +5 -0
- data/lib/graphql/tracing/legacy_trace.rb +1 -0
- data/lib/graphql/tracing/monitor_trace.rb +17 -11
- data/lib/graphql/tracing/new_relic_trace.rb +17 -8
- data/lib/graphql/tracing/new_relic_tracing.rb +7 -3
- data/lib/graphql/tracing/notifications_trace.rb +11 -8
- data/lib/graphql/tracing/notifications_tracing.rb +23 -7
- data/lib/graphql/tracing/null_trace.rb +1 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +1 -0
- data/lib/graphql/tracing/perfetto_trace.rb +41 -19
- data/lib/graphql/tracing/platform_trace.rb +3 -1
- data/lib/graphql/tracing/platform_tracing.rb +16 -7
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +1 -0
- data/lib/graphql/tracing/prometheus_trace.rb +22 -13
- data/lib/graphql/tracing/prometheus_tracing.rb +1 -0
- data/lib/graphql/tracing/scout_trace.rb +10 -4
- data/lib/graphql/tracing/scout_tracing.rb +7 -3
- data/lib/graphql/tracing/sentry_trace.rb +12 -5
- data/lib/graphql/tracing/statsd_trace.rb +12 -6
- data/lib/graphql/tracing/statsd_tracing.rb +7 -1
- data/lib/graphql/tracing/trace.rb +231 -58
- data/lib/graphql/tracing.rb +25 -9
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/big_int.rb +1 -0
- data/lib/graphql/types/boolean.rb +1 -0
- data/lib/graphql/types/float.rb +1 -0
- data/lib/graphql/types/id.rb +1 -0
- data/lib/graphql/types/int.rb +2 -1
- data/lib/graphql/types/iso_8601_date.rb +21 -4
- data/lib/graphql/types/iso_8601_date_time.rb +33 -6
- data/lib/graphql/types/iso_8601_duration.rb +42 -9
- data/lib/graphql/types/json.rb +1 -0
- data/lib/graphql/types/relay/base_connection.rb +38 -32
- data/lib/graphql/types/relay/base_edge.rb +15 -9
- data/lib/graphql/types/relay/connection_behaviors.rb +19 -3
- data/lib/graphql/types/relay/edge_behaviors.rb +17 -4
- data/lib/graphql/types/relay/has_node_field.rb +6 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +6 -1
- data/lib/graphql/types/relay/node.rb +1 -0
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay/page_info.rb +1 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +1 -0
- data/lib/graphql/types/relay.rb +4 -3
- data/lib/graphql/types/string.rb +1 -0
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/unauthorized_enum_value_error.rb +4 -1
- data/lib/graphql/unauthorized_error.rb +11 -4
- data/lib/graphql/unauthorized_field_error.rb +4 -1
- data/lib/graphql/unresolved_type_error.rb +16 -5
- data/lib/graphql/version.rb +2 -1
- data/lib/graphql.rb +37 -9
- data/readme.md +1 -1
- metadata +89 -5
- data/.yardopts +0 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
require "graphql/pagination/connection"
|
|
3
4
|
require "monitor"
|
|
4
5
|
|
|
@@ -6,6 +7,10 @@ module GraphQL
|
|
|
6
7
|
module Pagination
|
|
7
8
|
# A generic class for working with database query objects.
|
|
8
9
|
class RelationConnection < Pagination::Connection
|
|
10
|
+
# Database limits and offsets must fit in a signed 64-bit integer.
|
|
11
|
+
MAX_OFFSET = (2**63) - 1
|
|
12
|
+
private_constant :MAX_OFFSET
|
|
13
|
+
|
|
9
14
|
def nodes
|
|
10
15
|
load_nodes
|
|
11
16
|
@nodes
|
|
@@ -29,6 +34,12 @@ module GraphQL
|
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
def has_next_page
|
|
37
|
+
# If the query loads the page anyway, load it now so its extra row answers this
|
|
38
|
+
if @has_next_page.nil? && peek_next_page? &&
|
|
39
|
+
(lookahead.selects?(:nodes) || lookahead.selects?(:edges) ||
|
|
40
|
+
page_info_selection.selects?(:start_cursor) || page_info_selection.selects?(:end_cursor))
|
|
41
|
+
load_nodes
|
|
42
|
+
end
|
|
32
43
|
if @has_next_page.nil?
|
|
33
44
|
@has_next_page = if before_offset && before_offset > 0
|
|
34
45
|
true
|
|
@@ -47,49 +58,112 @@ module GraphQL
|
|
|
47
58
|
|
|
48
59
|
def cursor_for(item)
|
|
49
60
|
load_nodes
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
position = cursor_index_for(item, nodes)
|
|
62
|
+
offset_cursor_for_position(position)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def cursor_for_position(item, position) # :nodoc:
|
|
66
|
+
if self.class.custom_cursor_for?(RelationConnection)
|
|
67
|
+
super
|
|
68
|
+
else
|
|
69
|
+
offset_cursor_for_position(position)
|
|
70
|
+
end
|
|
53
71
|
end
|
|
54
72
|
|
|
55
73
|
private
|
|
56
74
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
75
|
+
def offset_cursor_for_position(position)
|
|
76
|
+
# position in nodes + existing offset + 1 (because it's offset, not index)
|
|
77
|
+
offset = position + 1 + (@paged_nodes_offset || 0) - (relation_offset(items) || 0)
|
|
78
|
+
encode(offset.to_s)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# **Parameters**
|
|
82
|
+
#
|
|
83
|
+
# - `relation` (`Object`) — A database query object
|
|
84
|
+
# - `_initial_offset` (`Integer`) — The number of items already excluded from the relation
|
|
85
|
+
# - `size` (`Integer`) — The value against which we check the relation size
|
|
86
|
+
#
|
|
87
|
+
# **Returns**
|
|
88
|
+
#
|
|
89
|
+
# - `Boolean` — True if the number of items in this relation is larger than `size`
|
|
90
|
+
#
|
|
91
|
+
# :call-seq:
|
|
92
|
+
# relation_larger_than(Object relation, Integer _initial_offset, Integer size) -> bool
|
|
61
93
|
def relation_larger_than(relation, _initial_offset, size)
|
|
62
|
-
|
|
94
|
+
if (limit = relation_limit(relation)) && limit <= size
|
|
95
|
+
false
|
|
96
|
+
else
|
|
97
|
+
relation_count(set_limit(relation, size + 1)) == size + 1
|
|
98
|
+
end
|
|
63
99
|
end
|
|
64
100
|
|
|
65
|
-
#
|
|
66
|
-
#
|
|
101
|
+
# **Parameters**
|
|
102
|
+
#
|
|
103
|
+
# - `relation` (`Object`) — A database query object
|
|
104
|
+
#
|
|
105
|
+
# **Returns**
|
|
106
|
+
#
|
|
107
|
+
# - `Integer, nil` — The offset value, or nil if there isn't one
|
|
108
|
+
#
|
|
109
|
+
# :call-seq:
|
|
110
|
+
# relation_offset(Object relation) -> Integer | nil
|
|
67
111
|
def relation_offset(relation)
|
|
68
112
|
raise "#{self.class}#relation_offset(relation) must return the offset value for a #{relation.class} (#{relation.inspect})"
|
|
69
113
|
end
|
|
70
114
|
|
|
71
|
-
#
|
|
72
|
-
#
|
|
115
|
+
# **Parameters**
|
|
116
|
+
#
|
|
117
|
+
# - `relation` (`Object`) — A database query object
|
|
118
|
+
#
|
|
119
|
+
# **Returns**
|
|
120
|
+
#
|
|
121
|
+
# - `Integer, nil` — The limit value, or nil if there isn't one
|
|
122
|
+
#
|
|
123
|
+
# :call-seq:
|
|
124
|
+
# relation_limit(Object relation) -> Integer | nil
|
|
73
125
|
def relation_limit(relation)
|
|
74
126
|
raise "#{self.class}#relation_limit(relation) must return the limit value for a #{relation.class} (#{relation.inspect})"
|
|
75
127
|
end
|
|
76
128
|
|
|
77
|
-
#
|
|
78
|
-
#
|
|
129
|
+
# **Parameters**
|
|
130
|
+
#
|
|
131
|
+
# - `relation` (`Object`) — A database query object
|
|
132
|
+
#
|
|
133
|
+
# **Returns**
|
|
134
|
+
#
|
|
135
|
+
# - `Integer, nil` — The number of items in this relation (hopefully determined without loading all records into memory!)
|
|
136
|
+
#
|
|
137
|
+
# :call-seq:
|
|
138
|
+
# relation_count(Object relation) -> Integer | nil
|
|
79
139
|
def relation_count(relation)
|
|
80
140
|
raise "#{self.class}#relation_count(relation) must return the count of records for a #{relation.class} (#{relation.inspect})"
|
|
81
141
|
end
|
|
82
142
|
|
|
83
|
-
#
|
|
84
|
-
#
|
|
143
|
+
# **Parameters**
|
|
144
|
+
#
|
|
145
|
+
# - `relation` (`Object`) — A database query object
|
|
146
|
+
#
|
|
147
|
+
# **Returns**
|
|
148
|
+
#
|
|
149
|
+
# - `Object` — A modified query object which will return no records
|
|
150
|
+
#
|
|
151
|
+
# :call-seq:
|
|
152
|
+
# null_relation(Object relation) -> Object
|
|
85
153
|
def null_relation(relation)
|
|
86
154
|
raise "#{self.class}#null_relation(relation) must return an empty relation for a #{relation.class} (#{relation.inspect})"
|
|
87
155
|
end
|
|
88
156
|
|
|
89
|
-
#
|
|
157
|
+
# **Returns**
|
|
158
|
+
#
|
|
159
|
+
# - `Integer`
|
|
160
|
+
#
|
|
161
|
+
# :call-seq:
|
|
162
|
+
# offset_from_cursor(cursor) -> Integer
|
|
90
163
|
def offset_from_cursor(cursor)
|
|
91
|
-
offset = Integer(decode(cursor), 10, exception: false)
|
|
92
|
-
if offset.nil? || offset <= 0
|
|
164
|
+
offset = Integer(decode(cursor), 10, exception: false) #: Integer?
|
|
165
|
+
if offset.nil? || offset <= 0 || offset > MAX_OFFSET ||
|
|
166
|
+
offset + (relation_offset(items) || 0) > MAX_OFFSET
|
|
93
167
|
raise GraphQL::ExecutionError, "Invalid cursor: #{cursor.inspect}"
|
|
94
168
|
end
|
|
95
169
|
offset
|
|
@@ -126,20 +200,21 @@ module GraphQL
|
|
|
126
200
|
|
|
127
201
|
if after_offset
|
|
128
202
|
next_offset += after_offset
|
|
203
|
+
relation_limit = [relation_limit - after_offset, 0].max if relation_limit
|
|
129
204
|
end
|
|
130
205
|
|
|
131
206
|
if before_offset && after_offset
|
|
132
207
|
if after_offset < before_offset
|
|
133
208
|
# Get the number of items between the two cursors
|
|
134
209
|
space_between = before_offset - after_offset - 1
|
|
135
|
-
relation_limit = space_between
|
|
210
|
+
relation_limit = [relation_limit, space_between].compact.min
|
|
136
211
|
else
|
|
137
212
|
# The cursors overextend one another to an empty set
|
|
138
213
|
@sliced_nodes_null_relation = true
|
|
139
214
|
end
|
|
140
215
|
elsif before_offset
|
|
141
216
|
# Use limit to cut off the tail of the relation
|
|
142
|
-
relation_limit = before_offset - 1
|
|
217
|
+
relation_limit = [relation_limit, before_offset - 1].compact.min
|
|
143
218
|
end
|
|
144
219
|
|
|
145
220
|
@sliced_nodes_limit = relation_limit
|
|
@@ -157,25 +232,35 @@ module GraphQL
|
|
|
157
232
|
if @sliced_nodes_null_relation
|
|
158
233
|
paginated_nodes = null_relation(paginated_nodes)
|
|
159
234
|
else
|
|
160
|
-
if @sliced_nodes_limit
|
|
161
|
-
paginated_nodes = set_limit(paginated_nodes, @sliced_nodes_limit)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
235
|
if @sliced_nodes_offset
|
|
165
236
|
paginated_nodes = set_offset(paginated_nodes, @sliced_nodes_offset)
|
|
166
237
|
end
|
|
238
|
+
|
|
239
|
+
if @sliced_nodes_limit
|
|
240
|
+
paginated_nodes = set_limit(paginated_nodes, @sliced_nodes_limit)
|
|
241
|
+
end
|
|
167
242
|
end
|
|
168
243
|
|
|
169
244
|
paginated_nodes
|
|
170
245
|
end
|
|
171
246
|
end
|
|
172
247
|
|
|
173
|
-
#
|
|
248
|
+
# **Returns**
|
|
249
|
+
#
|
|
250
|
+
# - `Integer, nil`
|
|
251
|
+
#
|
|
252
|
+
# :call-seq:
|
|
253
|
+
# before_offset() -> Integer | nil
|
|
174
254
|
def before_offset
|
|
175
255
|
@before_offset ||= before && offset_from_cursor(before)
|
|
176
256
|
end
|
|
177
257
|
|
|
178
|
-
#
|
|
258
|
+
# **Returns**
|
|
259
|
+
#
|
|
260
|
+
# - `Integer, nil`
|
|
261
|
+
#
|
|
262
|
+
# :call-seq:
|
|
263
|
+
# after_offset() -> Integer | nil
|
|
179
264
|
def after_offset
|
|
180
265
|
@after_offset ||= after && offset_from_cursor(after)
|
|
181
266
|
end
|
|
@@ -246,12 +331,35 @@ module GraphQL
|
|
|
246
331
|
# `AsyncDataloader` may resolve sibling fields (eg, `edges` and `pageInfo`)
|
|
247
332
|
# in separate Fibers, so several callers can get here before `@nodes` is set.
|
|
248
333
|
(@load_monitor ||= Monitor.new).synchronize do
|
|
249
|
-
|
|
334
|
+
# Not `||=`: Sorbet assumes `@nodes` is still falsy in this block
|
|
335
|
+
@nodes = load_page unless @nodes
|
|
250
336
|
end
|
|
251
337
|
else
|
|
252
|
-
@nodes =
|
|
338
|
+
@nodes = load_page
|
|
253
339
|
end
|
|
254
340
|
end
|
|
341
|
+
|
|
342
|
+
# Fetch one row past `first` so `has_next_page` needs no extra query.
|
|
343
|
+
# Skips arrays (no query to save) and slices limited to `first` or fewer rows (no next page).
|
|
344
|
+
def load_page
|
|
345
|
+
page = limited_nodes
|
|
346
|
+
return page.to_a if page.is_a?(Array) || !peek_next_page? || relation_limit(page) != first ||
|
|
347
|
+
(@sliced_nodes_limit && @sliced_nodes_limit <= first)
|
|
348
|
+
|
|
349
|
+
rows = set_limit(page, first + 1).to_a
|
|
350
|
+
@has_next_page = rows.size > first
|
|
351
|
+
rows.first(first)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Peek on forward pages that select `hasNextPage`; `last` and `before` keep the separate check
|
|
355
|
+
def peek_next_page?
|
|
356
|
+
return @peek_next_page if defined?(@peek_next_page)
|
|
357
|
+
@peek_next_page = first&.positive? && last.nil? && before.nil? && page_info_selection.selects?(:has_next_page)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def page_info_selection
|
|
361
|
+
@page_info_selection ||= (lookahead || GraphQL::Execution::Lookahead::NULL_LOOKAHEAD).selection(:page_info)
|
|
362
|
+
end
|
|
255
363
|
end
|
|
256
364
|
end
|
|
257
365
|
end
|
data/lib/graphql/pagination.rb
CHANGED
data/lib/graphql/parse_error.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
class Query
|
|
4
5
|
class Context
|
|
@@ -13,7 +14,7 @@ module GraphQL
|
|
|
13
14
|
if @scoped_contexts.nil?
|
|
14
15
|
GraphQL::EmptyObjects::EMPTY_HASH
|
|
15
16
|
else
|
|
16
|
-
merged_ctx = {}
|
|
17
|
+
merged_ctx = {} #: untyped
|
|
17
18
|
each_present_path_ctx do |path_ctx|
|
|
18
19
|
merged_ctx = path_ctx.merge(merged_ctx)
|
|
19
20
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
|
|
3
4
|
module GraphQL
|
|
4
5
|
class Query
|
|
@@ -31,18 +32,30 @@ module GraphQL
|
|
|
31
32
|
extend Forwardable
|
|
32
33
|
include Schema::Member::HasDataloader
|
|
33
34
|
|
|
34
|
-
#
|
|
35
|
+
# **Returns**
|
|
36
|
+
#
|
|
37
|
+
# - `Array<GraphQL::ExecutionError>` — errors returned during execution
|
|
35
38
|
attr_reader :errors
|
|
36
39
|
|
|
37
|
-
#
|
|
40
|
+
# **Returns**
|
|
41
|
+
#
|
|
42
|
+
# - `GraphQL::Query` — The query whose context this is
|
|
38
43
|
attr_reader :query
|
|
39
44
|
|
|
40
|
-
#
|
|
45
|
+
# **Returns**
|
|
46
|
+
#
|
|
47
|
+
# - `GraphQL::Schema`
|
|
41
48
|
attr_reader :schema
|
|
42
49
|
|
|
43
50
|
# Make a new context which delegates key lookup to `values`
|
|
44
|
-
#
|
|
45
|
-
#
|
|
51
|
+
#
|
|
52
|
+
# **Parameters**
|
|
53
|
+
#
|
|
54
|
+
# - `query` (`GraphQL::Query`) — the query who owns this context
|
|
55
|
+
# - `values` (`Hash`) — A hash of arbitrary values which will be accessible at query-time
|
|
56
|
+
#
|
|
57
|
+
# :call-seq:
|
|
58
|
+
# initialize(GraphQL::Query query:, schema:, Hash values:)
|
|
46
59
|
def initialize(query:, schema: query.schema, values:)
|
|
47
60
|
@query = query
|
|
48
61
|
@schema = schema
|
|
@@ -55,7 +68,13 @@ module GraphQL
|
|
|
55
68
|
end
|
|
56
69
|
|
|
57
70
|
# Modify this hash to return extensions to client.
|
|
58
|
-
#
|
|
71
|
+
#
|
|
72
|
+
# **Returns**
|
|
73
|
+
#
|
|
74
|
+
# - `Hash` — A hash that will be added verbatim to the result hash, as `"extensions" => { ... }`
|
|
75
|
+
#
|
|
76
|
+
# :call-seq:
|
|
77
|
+
# response_extensions() -> Hash
|
|
59
78
|
def response_extensions
|
|
60
79
|
namespace(:__query_result_extensions__)
|
|
61
80
|
end
|
|
@@ -64,14 +83,11 @@ module GraphQL
|
|
|
64
83
|
@dataloader ||= self[:dataloader] || (query.multiplex ? query.multiplex.dataloader : schema.dataloader_class.new)
|
|
65
84
|
end
|
|
66
85
|
|
|
67
|
-
#
|
|
68
|
-
attr_writer :interpreter
|
|
86
|
+
attr_writer :interpreter # :nodoc:
|
|
69
87
|
|
|
70
|
-
#
|
|
71
|
-
attr_writer :value
|
|
88
|
+
attr_writer :value # :nodoc:
|
|
72
89
|
|
|
73
|
-
#
|
|
74
|
-
attr_reader :scoped_context
|
|
90
|
+
attr_reader :scoped_context # :nodoc:
|
|
75
91
|
|
|
76
92
|
def []=(key, value)
|
|
77
93
|
@provided_values[key] = value
|
|
@@ -86,10 +102,9 @@ module GraphQL
|
|
|
86
102
|
attr_writer :types
|
|
87
103
|
|
|
88
104
|
RUNTIME_METADATA_KEYS = Set.new([:current_object, :current_arguments, :current_field, :current_path]).freeze
|
|
89
|
-
#
|
|
90
|
-
# Reassign `key` to the hash passed to {Schema#execute} as `context:`
|
|
105
|
+
# **Method:** `[]=(key, value)` — Reassign `key` to the hash passed to [Schema#execute](rdoc-ref:Schema#execute) as `context:`
|
|
91
106
|
|
|
92
|
-
# Lookup `key` from the hash passed to
|
|
107
|
+
# Lookup `key` from the hash passed to [Schema.execute](rdoc-ref:GraphQL::Schema.execute) as `context:`
|
|
93
108
|
def [](key)
|
|
94
109
|
if @scoped_context.key?(key)
|
|
95
110
|
@scoped_context[key]
|
|
@@ -116,8 +131,17 @@ module GraphQL
|
|
|
116
131
|
end
|
|
117
132
|
|
|
118
133
|
# Add error at query-level.
|
|
119
|
-
#
|
|
120
|
-
#
|
|
134
|
+
#
|
|
135
|
+
# **Parameters**
|
|
136
|
+
#
|
|
137
|
+
# - `error` (`GraphQL::ExecutionError`) — an execution error
|
|
138
|
+
#
|
|
139
|
+
# **Returns**
|
|
140
|
+
#
|
|
141
|
+
# - `void`
|
|
142
|
+
#
|
|
143
|
+
# :call-seq:
|
|
144
|
+
# add_error(GraphQL::ExecutionError error) -> void
|
|
121
145
|
def add_error(error)
|
|
122
146
|
if !error.is_a?(GraphQL::RuntimeError)
|
|
123
147
|
raise TypeError, "expected error to be a GraphQL::RuntimeError, but was #{error.class}"
|
|
@@ -126,16 +150,34 @@ module GraphQL
|
|
|
126
150
|
nil
|
|
127
151
|
end
|
|
128
152
|
|
|
129
|
-
#
|
|
130
|
-
#
|
|
153
|
+
# **Parameters**
|
|
154
|
+
#
|
|
155
|
+
# - `value` (`Object`) — Any object to be inserted directly into the final response
|
|
156
|
+
#
|
|
157
|
+
# **Returns**
|
|
158
|
+
#
|
|
159
|
+
# - `GraphQL::Execution::Interpreter::RawValue` — Return this from the field
|
|
160
|
+
#
|
|
161
|
+
# :call-seq:
|
|
162
|
+
# raw_value(Object value) -> GraphQL::Execution::Interpreter::RawValue
|
|
131
163
|
def raw_value(value)
|
|
132
164
|
GraphQL::Execution::Interpreter::RawValue.new(value)
|
|
133
165
|
end
|
|
134
166
|
|
|
135
|
-
#
|
|
136
|
-
# puts ctx.backtrace
|
|
167
|
+
# **Examples**
|
|
137
168
|
#
|
|
138
|
-
#
|
|
169
|
+
# **Example: Print the GraphQL backtrace during field resolution**
|
|
170
|
+
#
|
|
171
|
+
# ```ruby
|
|
172
|
+
# puts ctx.backtrace
|
|
173
|
+
# ```
|
|
174
|
+
#
|
|
175
|
+
# **Returns**
|
|
176
|
+
#
|
|
177
|
+
# - `GraphQL::Backtrace` — The backtrace for this point in query execution
|
|
178
|
+
#
|
|
179
|
+
# :call-seq:
|
|
180
|
+
# backtrace() -> GraphQL::Backtrace
|
|
139
181
|
def backtrace
|
|
140
182
|
GraphQL::Backtrace.new(self)
|
|
141
183
|
end
|
|
@@ -217,17 +259,30 @@ module GraphQL
|
|
|
217
259
|
@scoped_context.key?(key) || @provided_values.key?(key)
|
|
218
260
|
end
|
|
219
261
|
|
|
220
|
-
#
|
|
262
|
+
# **Returns**
|
|
263
|
+
#
|
|
264
|
+
# - `GraphQL::Schema::Warden`
|
|
265
|
+
#
|
|
266
|
+
# :call-seq:
|
|
267
|
+
# warden() -> GraphQL::Schema::Warden
|
|
221
268
|
def warden
|
|
222
269
|
@warden ||= (@query && @query.warden)
|
|
223
270
|
end
|
|
224
271
|
|
|
225
|
-
#
|
|
226
|
-
attr_writer :warden
|
|
272
|
+
attr_writer :warden # :nodoc:
|
|
227
273
|
|
|
228
274
|
# Get an isolated hash for `ns`. Doesn't affect user-provided storage.
|
|
229
|
-
#
|
|
230
|
-
#
|
|
275
|
+
#
|
|
276
|
+
# **Parameters**
|
|
277
|
+
#
|
|
278
|
+
# - `ns` (`Object`) — a usage-specific namespace identifier
|
|
279
|
+
#
|
|
280
|
+
# **Returns**
|
|
281
|
+
#
|
|
282
|
+
# - `Hash` — namespaced storage
|
|
283
|
+
#
|
|
284
|
+
# :call-seq:
|
|
285
|
+
# namespace(Object ns) -> Hash
|
|
231
286
|
def namespace(ns)
|
|
232
287
|
if ns == :interpreter
|
|
233
288
|
self
|
|
@@ -236,7 +291,12 @@ module GraphQL
|
|
|
236
291
|
end
|
|
237
292
|
end
|
|
238
293
|
|
|
239
|
-
#
|
|
294
|
+
# **Returns**
|
|
295
|
+
#
|
|
296
|
+
# - `Boolean` — true if this namespace was accessed before
|
|
297
|
+
#
|
|
298
|
+
# :call-seq:
|
|
299
|
+
# namespace?(ns) -> bool
|
|
240
300
|
def namespace?(ns)
|
|
241
301
|
@storage.key?(ns)
|
|
242
302
|
end
|
|
@@ -261,13 +321,24 @@ module GraphQL
|
|
|
261
321
|
# Use this when you need to do a scoped set _inside_ a lazy-loaded (or batch-loaded)
|
|
262
322
|
# block of code.
|
|
263
323
|
#
|
|
264
|
-
#
|
|
265
|
-
#
|
|
266
|
-
#
|
|
267
|
-
#
|
|
268
|
-
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
324
|
+
# **Examples**
|
|
325
|
+
#
|
|
326
|
+
# **Example: using scoped context inside a promise**
|
|
327
|
+
#
|
|
328
|
+
# ```ruby
|
|
329
|
+
# scoped_ctx = context.scoped
|
|
330
|
+
# SomeBatchLoader.load(...).then do |thing|
|
|
331
|
+
# # use a scoped_ctx which was created _before_ dataloading:
|
|
332
|
+
# scoped_ctx.set!(:thing, thing)
|
|
333
|
+
# end
|
|
334
|
+
# ```
|
|
335
|
+
#
|
|
336
|
+
# **Returns**
|
|
337
|
+
#
|
|
338
|
+
# - `Context::Scoped`
|
|
339
|
+
#
|
|
340
|
+
# :call-seq:
|
|
341
|
+
# scoped() -> Context::Scoped
|
|
271
342
|
def scoped
|
|
272
343
|
Scoped.new(@scoped_context, current_path)
|
|
273
344
|
end
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
|
|
3
4
|
require 'digest/sha2'
|
|
4
5
|
|
|
5
6
|
module GraphQL
|
|
6
7
|
class Query
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
# @see Query#fingerprint
|
|
11
|
-
module Fingerprint
|
|
8
|
+
# The resulting hashes are exposed by `Query#operation_fingerprint`,
|
|
9
|
+
# `Query#variables_fingerprint`, and `Query#fingerprint`.
|
|
10
|
+
module Fingerprint # :nodoc:
|
|
12
11
|
# Make an obfuscated hash of the given string (either a query string or variables JSON)
|
|
13
|
-
#
|
|
14
|
-
#
|
|
12
|
+
#
|
|
13
|
+
# **Parameters**
|
|
14
|
+
#
|
|
15
|
+
# - `string` (`String`)
|
|
16
|
+
#
|
|
17
|
+
# **Returns**
|
|
18
|
+
#
|
|
19
|
+
# - `String` — A normalized, opaque hash
|
|
20
|
+
#
|
|
21
|
+
# :call-seq:
|
|
22
|
+
# generate(input_str) -> String
|
|
15
23
|
def self.generate(input_str)
|
|
16
24
|
# Implemented to be:
|
|
17
25
|
# - Short (and uniform) length
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
class Query
|
|
4
|
-
# This class is _like_ a
|
|
5
|
+
# This class is _like_ a [GraphQL::Query](rdoc-ref:GraphQL::Query), except it can run on an arbitrary path within a query string.
|
|
5
6
|
#
|
|
6
|
-
# It depends on a "parent"
|
|
7
|
+
# It depends on a "parent" [Query](rdoc-ref:Query).
|
|
7
8
|
#
|
|
8
9
|
# During execution, it calls query-related tracing hooks but passes itself as `query:`.
|
|
9
10
|
#
|
|
10
|
-
# The
|
|
11
|
+
# The [Partial](rdoc-ref:Partial) will use your [Schema.resolve_type](rdoc-ref:Schema.resolve_type) hook to find the right GraphQL type to use for
|
|
11
12
|
# `object` in some cases.
|
|
12
13
|
#
|
|
13
|
-
#
|
|
14
|
+
# Run via [Query#run_partials](rdoc-ref:Query#run_partials).
|
|
14
15
|
class Partial
|
|
15
16
|
include Query::Runnable
|
|
16
17
|
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
18
|
+
# **Parameters**
|
|
19
|
+
#
|
|
20
|
+
# - `path` (`Array<String, Integer>`) — A path in `query.query_string` to start executing from
|
|
21
|
+
# - `object` (`Object`) — A starting object for execution
|
|
22
|
+
# - `query` (`GraphQL::Query`) — A full query instance that this partial is based on. Caches are shared.
|
|
23
|
+
# - `context` (`Hash`) — Extra context values to merge into `query.context`, if provided
|
|
24
|
+
# - `fragment_node` (`GraphQL::Language::Nodes::InlineFragment, GraphQL::Language::Nodes::FragmentDefinition`)
|
|
25
|
+
#
|
|
26
|
+
# :call-seq:
|
|
27
|
+
# initialize(Array[String | Integer] path:, Object object:, GraphQL::Query query:, Hash context:, GraphQL::Language::Nodes::InlineFragment | GraphQL::Language::Nodes::FragmentDefinition fragment_node:, type:)
|
|
22
28
|
def initialize(path: nil, object:, query:, context: nil, fragment_node: nil, type: nil)
|
|
23
29
|
@path = path
|
|
24
30
|
@object = object
|
|
@@ -65,7 +71,12 @@ module GraphQL
|
|
|
65
71
|
@query.path
|
|
66
72
|
end
|
|
67
73
|
|
|
68
|
-
#
|
|
74
|
+
# **Returns**
|
|
75
|
+
#
|
|
76
|
+
# - `GraphQL::Query::Partial`
|
|
77
|
+
#
|
|
78
|
+
# :call-seq:
|
|
79
|
+
# partial() -> GraphQL::Query::Partial
|
|
69
80
|
def partial
|
|
70
81
|
@query
|
|
71
82
|
end
|
|
@@ -138,9 +149,9 @@ module GraphQL
|
|
|
138
149
|
private
|
|
139
150
|
|
|
140
151
|
def set_type_info_from_path
|
|
141
|
-
selections = [@query.selected_operation]
|
|
152
|
+
selections = [@query.selected_operation] #: Array[GraphQL::Language::Nodes::OperationDefinition | GraphQL::Language::Nodes::Field]
|
|
142
153
|
type = @query.root_type
|
|
143
|
-
field_defn = nil
|
|
154
|
+
field_defn = nil #: GraphQL::Schema::Field?
|
|
144
155
|
|
|
145
156
|
@path.each do |name_in_doc|
|
|
146
157
|
if name_in_doc.is_a?(Integer)
|
|
@@ -152,9 +163,9 @@ module GraphQL
|
|
|
152
163
|
end
|
|
153
164
|
end
|
|
154
165
|
|
|
155
|
-
next_selections = []
|
|
166
|
+
next_selections = [] #: Array[GraphQL::Language::Nodes::Field]
|
|
156
167
|
selections.each do |selection|
|
|
157
|
-
selections_to_check = []
|
|
168
|
+
selections_to_check = [] #: Array[GraphQL::Language::Nodes::Field | GraphQL::Language::Nodes::InlineFragment | GraphQL::Language::Nodes::FragmentSpread]
|
|
158
169
|
selections_to_check.concat(selection.selections)
|
|
159
170
|
while (sel = selections_to_check.shift)
|
|
160
171
|
case sel
|
|
@@ -168,7 +179,7 @@ module GraphQL
|
|
|
168
179
|
next_selections << sel
|
|
169
180
|
end
|
|
170
181
|
else
|
|
171
|
-
raise "Unexpected selection in partial path: #{sel.class}, #{sel.inspect}"
|
|
182
|
+
raise "Unexpected selection in partial path: #{sel.class}, #{sel.inspect}" #: absurd(sel)
|
|
172
183
|
end
|
|
173
184
|
end
|
|
174
185
|
end
|
|
@@ -176,7 +187,8 @@ module GraphQL
|
|
|
176
187
|
if next_selections.empty?
|
|
177
188
|
raise ArgumentError, "Path `#{@path.inspect}` is not present in this query. `#{name_in_doc.inspect}` was not found. Try a different path or rewrite the query to include it."
|
|
178
189
|
end
|
|
179
|
-
|
|
190
|
+
first_selection = next_selections.first #: as !nil
|
|
191
|
+
field_name = first_selection.name
|
|
180
192
|
field_defn = @schema.get_field(type, field_name, @query.context) || raise("Invariant: no field called #{field_name} on #{type.graphql_name}")
|
|
181
193
|
type = field_defn.type
|
|
182
194
|
if type.non_null?
|