graphql 2.0.31 → 2.6.1
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/lib/generators/graphql/detailed_trace_generator.rb +77 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
- data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +49 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +2 -0
- data/lib/generators/graphql/templates/base_edge.erb +2 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_resolver.erb +8 -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/create_graphql_detailed_traces.erb +10 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +2 -0
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +5 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyzer.rb +90 -0
- data/lib/graphql/analysis/field_usage.rb +82 -0
- data/lib/graphql/analysis/max_query_complexity.rb +20 -0
- data/lib/graphql/analysis/max_query_depth.rb +20 -0
- data/lib/graphql/analysis/query_complexity.rb +263 -0
- data/lib/graphql/analysis/query_depth.rb +58 -0
- data/lib/graphql/analysis/visitor.rb +280 -0
- data/lib/graphql/analysis.rb +102 -1
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/backtrace/table.rb +118 -55
- data/lib/graphql/backtrace.rb +1 -19
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/current.rb +57 -0
- data/lib/graphql/dashboard/application_controller.rb +41 -0
- data/lib/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -0
- data/lib/graphql/dashboard/landings_controller.rb +9 -0
- data/lib/graphql/dashboard/limiters.rb +93 -0
- data/lib/graphql/dashboard/operation_store.rb +199 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/charts.min.css +1 -0
- data/lib/graphql/dashboard/statics/dashboard.css +30 -0
- data/lib/graphql/dashboard/statics/dashboard.js +143 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/statics_controller.rb +31 -0
- data/lib/graphql/dashboard/subscriptions.rb +97 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +24 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
- data/lib/graphql/dashboard.rb +96 -0
- data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
- data/lib/graphql/dataloader/active_record_source.rb +47 -0
- data/lib/graphql/dataloader/async_dataloader.rb +112 -0
- data/lib/graphql/dataloader/null_dataloader.rb +55 -10
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/dataloader/source.rb +35 -12
- data/lib/graphql/dataloader.rb +224 -149
- data/lib/graphql/date_encoding_error.rb +1 -1
- data/lib/graphql/dig.rb +2 -1
- data/lib/graphql/duration_encoding_error.rb +16 -0
- data/lib/graphql/execution/field_resolve_step.rb +631 -0
- data/lib/graphql/execution/finalize.rb +217 -0
- data/lib/graphql/execution/input_values.rb +261 -0
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +6 -0
- data/lib/graphql/execution/interpreter/resolve.rb +23 -25
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +228 -0
- data/lib/graphql/execution/interpreter/runtime.rb +365 -435
- data/lib/graphql/execution/interpreter.rb +87 -163
- data/lib/graphql/execution/lazy.rb +1 -1
- data/lib/graphql/execution/load_argument_step.rb +64 -0
- data/lib/graphql/execution/lookahead.rb +105 -31
- data/lib/graphql/execution/multiplex.rb +7 -6
- data/lib/graphql/execution/next.rb +90 -0
- data/lib/graphql/execution/prepare_object_step.rb +128 -0
- data/lib/graphql/execution/runner.rb +410 -0
- data/lib/graphql/execution/selections_step.rb +91 -0
- data/lib/graphql/execution.rb +8 -4
- data/lib/graphql/execution_error.rb +17 -10
- data/lib/graphql/introspection/directive_location_enum.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +7 -3
- data/lib/graphql/introspection/dynamic_fields.rb +5 -1
- data/lib/graphql/introspection/entry_points.rb +20 -6
- data/lib/graphql/introspection/enum_value_type.rb +5 -5
- data/lib/graphql/introspection/field_type.rb +13 -5
- data/lib/graphql/introspection/input_value_type.rb +21 -13
- data/lib/graphql/introspection/schema_type.rb +8 -11
- data/lib/graphql/introspection/type_type.rb +64 -28
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +26 -17
- data/lib/graphql/language/block_string.rb +34 -18
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +90 -61
- data/lib/graphql/language/lexer.rb +323 -193
- data/lib/graphql/language/nodes.rb +139 -77
- data/lib/graphql/language/parser.rb +807 -1985
- data/lib/graphql/language/printer.rb +324 -151
- data/lib/graphql/language/sanitized_printer.rb +21 -23
- data/lib/graphql/language/static_visitor.rb +171 -0
- data/lib/graphql/language/visitor.rb +62 -119
- data/lib/graphql/language.rb +71 -1
- data/lib/graphql/load_application_object_failed_error.rb +5 -1
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/pagination/connection.rb +30 -1
- data/lib/graphql/pagination/connections.rb +32 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
- data/lib/graphql/query/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +88 -144
- data/lib/graphql/query/null_context.rb +15 -18
- data/lib/graphql/query/partial.rb +194 -0
- data/lib/graphql/query/validation_pipeline.rb +4 -4
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +135 -81
- data/lib/graphql/railtie.rb +16 -6
- data/lib/graphql/rake_task.rb +3 -12
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
- data/lib/graphql/rubocop.rb +2 -0
- data/lib/graphql/runtime_error.rb +6 -0
- data/lib/graphql/schema/addition.rb +26 -13
- data/lib/graphql/schema/always_visible.rb +7 -2
- data/lib/graphql/schema/argument.rb +78 -14
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +140 -66
- data/lib/graphql/schema/directive/flagged.rb +4 -2
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive.rb +78 -12
- data/lib/graphql/schema/enum.rb +110 -27
- data/lib/graphql/schema/enum_value.rb +11 -3
- data/lib/graphql/schema/field/connection_extension.rb +4 -51
- data/lib/graphql/schema/field/scope_extension.rb +19 -7
- data/lib/graphql/schema/field.rb +245 -119
- data/lib/graphql/schema/field_extension.rb +12 -9
- data/lib/graphql/schema/has_single_input_argument.rb +160 -0
- data/lib/graphql/schema/input_object.rb +123 -65
- data/lib/graphql/schema/interface.rb +60 -16
- data/lib/graphql/schema/introspection_system.rb +8 -17
- data/lib/graphql/schema/late_bound_type.rb +4 -0
- data/lib/graphql/schema/list.rb +8 -4
- data/lib/graphql/schema/loader.rb +3 -4
- data/lib/graphql/schema/member/base_dsl_methods.rb +18 -12
- data/lib/graphql/schema/member/has_arguments.rb +132 -100
- data/lib/graphql/schema/member/has_authorization.rb +35 -0
- data/lib/graphql/schema/member/has_dataloader.rb +99 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
- data/lib/graphql/schema/member/has_directives.rb +5 -5
- data/lib/graphql/schema/member/has_fields.rb +121 -17
- data/lib/graphql/schema/member/has_interfaces.rb +27 -13
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +18 -5
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/non_null.rb +1 -1
- data/lib/graphql/schema/object.rb +34 -8
- data/lib/graphql/schema/printer.rb +9 -7
- data/lib/graphql/schema/ractor_shareable.rb +79 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +6 -129
- data/lib/graphql/schema/resolver.rb +128 -32
- data/lib/graphql/schema/scalar.rb +4 -9
- data/lib/graphql/schema/subscription.rb +63 -12
- data/lib/graphql/schema/timeout.rb +19 -2
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.rb +2 -2
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- data/lib/graphql/schema/validator/required_validator.rb +92 -11
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +188 -0
- data/lib/graphql/schema/visibility/profile.rb +464 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +311 -0
- data/lib/graphql/schema/warden.rb +275 -103
- data/lib/graphql/schema/wrapper.rb +7 -1
- data/lib/graphql/schema.rb +954 -212
- data/lib/graphql/static_validation/all_rules.rb +3 -3
- data/lib/graphql/static_validation/base_visitor.rb +96 -71
- data/lib/graphql/static_validation/literal_validator.rb +6 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +2 -2
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +18 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +6 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +6 -3
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +14 -3
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +59 -15
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +391 -262
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +6 -6
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +15 -2
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +28 -8
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +14 -2
- data/lib/graphql/static_validation/validation_context.rb +22 -6
- data/lib/graphql/static_validation/validator.rb +9 -1
- data/lib/graphql/static_validation.rb +0 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -5
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +45 -19
- data/lib/graphql/subscriptions/event.rb +22 -4
- data/lib/graphql/subscriptions/serialize.rb +3 -1
- data/lib/graphql/subscriptions.rb +56 -17
- data/lib/graphql/testing/helpers.rb +161 -0
- data/lib/graphql/testing/mock_action_cable.rb +111 -0
- data/lib/graphql/testing.rb +3 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
- data/lib/graphql/tracing/appoptics_trace.rb +11 -3
- data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
- data/lib/graphql/tracing/appsignal_trace.rb +32 -55
- data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +46 -158
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +74 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +156 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +75 -0
- data/lib/graphql/tracing/legacy_trace.rb +4 -61
- data/lib/graphql/tracing/monitor_trace.rb +283 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -54
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +184 -34
- data/lib/graphql/tracing/notifications_tracing.rb +2 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
- data/lib/graphql/tracing/perfetto_trace.rb +864 -0
- data/lib/graphql/tracing/platform_trace.rb +5 -0
- data/lib/graphql/tracing/platform_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
- data/lib/graphql/tracing/prometheus_trace.rb +72 -68
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -55
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +82 -0
- data/lib/graphql/tracing/statsd_trace.rb +33 -41
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +118 -1
- data/lib/graphql/tracing.rb +31 -28
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +45 -3
- data/lib/graphql/types/relay/edge_behaviors.rb +19 -1
- data/lib/graphql/types/relay/has_node_field.rb +13 -8
- data/lib/graphql/types/relay/has_nodes_field.rb +13 -8
- data/lib/graphql/types/relay/node_behaviors.rb +13 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -10
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/unauthorized_error.rb +9 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +69 -54
- data/readme.md +12 -2
- metadata +236 -40
- data/lib/graphql/analysis/ast/analyzer.rb +0 -84
- data/lib/graphql/analysis/ast/field_usage.rb +0 -57
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
- data/lib/graphql/analysis/ast/query_depth.rb +0 -55
- data/lib/graphql/analysis/ast/visitor.rb +0 -276
- data/lib/graphql/analysis/ast.rb +0 -81
- data/lib/graphql/backtrace/inspect_result.rb +0 -50
- data/lib/graphql/backtrace/trace.rb +0 -96
- data/lib/graphql/backtrace/tracer.rb +0 -80
- data/lib/graphql/deprecation.rb +0 -9
- data/lib/graphql/filter.rb +0 -59
- data/lib/graphql/language/parser.y +0 -560
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
- data/lib/graphql/schema/null_mask.rb +0 -11
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module GraphQL
|
|
3
|
+
class Query
|
|
4
|
+
# This class is _like_ a {GraphQL::Query}, except it can run on an arbitrary path within a query string.
|
|
5
|
+
#
|
|
6
|
+
# It depends on a "parent" {Query}.
|
|
7
|
+
#
|
|
8
|
+
# During execution, it calls query-related tracing hooks but passes itself as `query:`.
|
|
9
|
+
#
|
|
10
|
+
# The {Partial} will use your {Schema.resolve_type} hook to find the right GraphQL type to use for
|
|
11
|
+
# `object` in some cases.
|
|
12
|
+
#
|
|
13
|
+
# @see Query#run_partials Run via {Query#run_partials}
|
|
14
|
+
class Partial
|
|
15
|
+
include Query::Runnable
|
|
16
|
+
|
|
17
|
+
# @param path [Array<String, Integer>] A path in `query.query_string` to start executing from
|
|
18
|
+
# @param object [Object] A starting object for execution
|
|
19
|
+
# @param query [GraphQL::Query] A full query instance that this partial is based on. Caches are shared.
|
|
20
|
+
# @param context [Hash] Extra context values to merge into `query.context`, if provided
|
|
21
|
+
# @param fragment_node [GraphQL::Language::Nodes::InlineFragment, GraphQL::Language::Nodes::FragmentDefinition]
|
|
22
|
+
def initialize(path: nil, object:, query:, context: nil, fragment_node: nil, type: nil)
|
|
23
|
+
@path = path
|
|
24
|
+
@object = object
|
|
25
|
+
@query = query
|
|
26
|
+
@schema = query.schema
|
|
27
|
+
context_vals = @query.context.to_h
|
|
28
|
+
if context
|
|
29
|
+
context_vals = context_vals.merge(context)
|
|
30
|
+
end
|
|
31
|
+
@context = GraphQL::Query::Context.new(query: self, schema: @query.schema, values: context_vals)
|
|
32
|
+
@multiplex = nil
|
|
33
|
+
@result_values = nil
|
|
34
|
+
@result = nil
|
|
35
|
+
@finalizers = @top_level_finalizers = nil
|
|
36
|
+
|
|
37
|
+
if fragment_node
|
|
38
|
+
@ast_nodes = [fragment_node]
|
|
39
|
+
@root_type = type || raise(ArgumentError, "Pass `type:` when using `node:`")
|
|
40
|
+
# This is only used when `@leaf`
|
|
41
|
+
@field_definition = nil
|
|
42
|
+
elsif path.nil?
|
|
43
|
+
raise ArgumentError, "`path:` is required if `node:` is not given; add `path:`"
|
|
44
|
+
else
|
|
45
|
+
set_type_info_from_path
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@leaf = @root_type.unwrap.kind.leaf?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def leaf?
|
|
52
|
+
@leaf
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def root_value
|
|
56
|
+
object
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
attr_reader :context, :query, :ast_nodes, :root_type, :object, :field_definition, :path, :schema
|
|
60
|
+
|
|
61
|
+
attr_accessor :multiplex, :result_values
|
|
62
|
+
|
|
63
|
+
class Result < GraphQL::Query::Result
|
|
64
|
+
def path
|
|
65
|
+
@query.path
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [GraphQL::Query::Partial]
|
|
69
|
+
def partial
|
|
70
|
+
@query
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def result
|
|
75
|
+
@result ||= Result.new(query: self, values: result_values)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def current_trace
|
|
79
|
+
@query.current_trace
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def types
|
|
83
|
+
@query.types
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def resolve_type(...)
|
|
87
|
+
@query.resolve_type(...)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def variables
|
|
91
|
+
@query.variables
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def fragments
|
|
95
|
+
@query.fragments
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def validate
|
|
99
|
+
@query.validate
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def valid?
|
|
103
|
+
@query.valid?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def query?
|
|
107
|
+
true
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def run_partials(...)
|
|
111
|
+
@query.run_partials(...)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def analyzers
|
|
115
|
+
EmptyObjects::EMPTY_ARRAY
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def analysis_errors=(_ignored)
|
|
119
|
+
# pass
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def subscription?
|
|
123
|
+
@query.subscription?
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def selected_operation
|
|
127
|
+
Language::Nodes::OperationDefinition.new(selections: ast_nodes.flat_map(&:selections))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def static_errors
|
|
131
|
+
@query.static_errors
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def selected_operation_name
|
|
135
|
+
@query.selected_operation_name
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
private
|
|
139
|
+
|
|
140
|
+
def set_type_info_from_path
|
|
141
|
+
selections = [@query.selected_operation]
|
|
142
|
+
type = @query.root_type
|
|
143
|
+
field_defn = nil
|
|
144
|
+
|
|
145
|
+
@path.each do |name_in_doc|
|
|
146
|
+
if name_in_doc.is_a?(Integer)
|
|
147
|
+
if type.list?
|
|
148
|
+
type = type.unwrap
|
|
149
|
+
next
|
|
150
|
+
else
|
|
151
|
+
raise ArgumentError, "Received path with index `#{name_in_doc}`, but type wasn't a list. Type: #{type.to_type_signature}, path: #{@path}"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
next_selections = []
|
|
156
|
+
selections.each do |selection|
|
|
157
|
+
selections_to_check = []
|
|
158
|
+
selections_to_check.concat(selection.selections)
|
|
159
|
+
while (sel = selections_to_check.shift)
|
|
160
|
+
case sel
|
|
161
|
+
when GraphQL::Language::Nodes::InlineFragment
|
|
162
|
+
selections_to_check.concat(sel.selections)
|
|
163
|
+
when GraphQL::Language::Nodes::FragmentSpread
|
|
164
|
+
fragment = @query.fragments[sel.name]
|
|
165
|
+
selections_to_check.concat(fragment.selections)
|
|
166
|
+
when GraphQL::Language::Nodes::Field
|
|
167
|
+
if sel.alias == name_in_doc || sel.name == name_in_doc
|
|
168
|
+
next_selections << sel
|
|
169
|
+
end
|
|
170
|
+
else
|
|
171
|
+
raise "Unexpected selection in partial path: #{sel.class}, #{sel.inspect}"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
if next_selections.empty?
|
|
177
|
+
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
|
+
end
|
|
179
|
+
field_name = next_selections.first.name
|
|
180
|
+
field_defn = @schema.get_field(type, field_name, @query.context) || raise("Invariant: no field called #{field_name} on #{type.graphql_name}")
|
|
181
|
+
type = field_defn.type
|
|
182
|
+
if type.non_null?
|
|
183
|
+
type = type.of_type
|
|
184
|
+
end
|
|
185
|
+
selections = next_selections
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
@ast_nodes = selections
|
|
189
|
+
@root_type = type
|
|
190
|
+
@field_definition = field_defn
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -14,7 +14,7 @@ module GraphQL
|
|
|
14
14
|
#
|
|
15
15
|
# @api private
|
|
16
16
|
class ValidationPipeline
|
|
17
|
-
attr_reader :max_depth, :max_complexity
|
|
17
|
+
attr_reader :max_depth, :max_complexity, :validate_timeout_remaining
|
|
18
18
|
|
|
19
19
|
def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
|
|
20
20
|
@validation_errors = []
|
|
@@ -71,7 +71,7 @@ module GraphQL
|
|
|
71
71
|
validator = @query.static_validator || @schema.static_validator
|
|
72
72
|
validation_result = validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
|
|
73
73
|
@validation_errors.concat(validation_result[:errors])
|
|
74
|
-
|
|
74
|
+
@validate_timeout_remaining = validation_result[:remaining_timeout]
|
|
75
75
|
if @validation_errors.empty?
|
|
76
76
|
@validation_errors.concat(@query.variables.errors)
|
|
77
77
|
end
|
|
@@ -100,10 +100,10 @@ module GraphQL
|
|
|
100
100
|
# Depending on the analysis engine, we must use different analyzers
|
|
101
101
|
# remove this once everything has switched over to AST analyzers
|
|
102
102
|
if max_depth
|
|
103
|
-
qa << GraphQL::Analysis::
|
|
103
|
+
qa << GraphQL::Analysis::MaxQueryDepth
|
|
104
104
|
end
|
|
105
105
|
if max_complexity
|
|
106
|
-
qa << GraphQL::Analysis::
|
|
106
|
+
qa << GraphQL::Analysis::MaxQueryComplexity
|
|
107
107
|
end
|
|
108
108
|
qa
|
|
109
109
|
else
|
|
@@ -26,7 +26,7 @@ module GraphQL
|
|
|
26
26
|
# - Then, fall back to the default value from the query string
|
|
27
27
|
# If it's still nil, raise an error if it's required.
|
|
28
28
|
variable_type = schema.type_from_ast(ast_variable.type, context: ctx)
|
|
29
|
-
if variable_type.nil?
|
|
29
|
+
if variable_type.nil? || !variable_type.unwrap.kind.input?
|
|
30
30
|
# Pass -- it will get handled by a validator
|
|
31
31
|
else
|
|
32
32
|
variable_name = ast_variable.name
|
|
@@ -80,12 +80,12 @@ module GraphQL
|
|
|
80
80
|
else
|
|
81
81
|
val
|
|
82
82
|
end
|
|
83
|
-
end
|
|
83
|
+
end
|
|
84
84
|
|
|
85
85
|
def add_max_errors_reached_message
|
|
86
86
|
message = "Too many errors processing variables, max validation error limit reached. Execution aborted"
|
|
87
87
|
validation_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
|
88
|
-
errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
|
|
88
|
+
errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
end
|
data/lib/graphql/query.rb
CHANGED
|
@@ -1,19 +1,56 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require "graphql/query/context"
|
|
3
|
-
require "graphql/query/fingerprint"
|
|
4
|
-
require "graphql/query/null_context"
|
|
5
|
-
require "graphql/query/result"
|
|
6
|
-
require "graphql/query/variables"
|
|
7
|
-
require "graphql/query/input_validation_result"
|
|
8
|
-
require "graphql/query/variable_validation_error"
|
|
9
|
-
require "graphql/query/validation_pipeline"
|
|
10
2
|
|
|
11
3
|
module GraphQL
|
|
12
4
|
# A combination of query string and {Schema} instance which can be reduced to a {#result}.
|
|
13
5
|
class Query
|
|
6
|
+
extend Autoload
|
|
14
7
|
include Tracing::Traceable
|
|
15
8
|
extend Forwardable
|
|
16
9
|
|
|
10
|
+
autoload :Context, "graphql/query/context"
|
|
11
|
+
autoload :Fingerprint, "graphql/query/fingerprint"
|
|
12
|
+
autoload :NullContext, "graphql/query/null_context"
|
|
13
|
+
autoload :Partial, "graphql/query/partial"
|
|
14
|
+
autoload :Result, "graphql/query/result"
|
|
15
|
+
autoload :Variables, "graphql/query/variables"
|
|
16
|
+
autoload :InputValidationResult, "graphql/query/input_validation_result"
|
|
17
|
+
autoload :VariableValidationError, "graphql/query/variable_validation_error"
|
|
18
|
+
autoload :ValidationPipeline, "graphql/query/validation_pipeline"
|
|
19
|
+
|
|
20
|
+
# Code shared with {Partial}
|
|
21
|
+
module Runnable
|
|
22
|
+
def after_lazy(value, &block)
|
|
23
|
+
if !defined?(@runtime_instance)
|
|
24
|
+
@runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if @runtime_instance
|
|
28
|
+
@runtime_instance.minimal_after_lazy(value, &block)
|
|
29
|
+
else
|
|
30
|
+
@schema.after_lazy(value, &block)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Node-level cache for calculating arguments. Used during execution and query analysis.
|
|
35
|
+
# @param ast_node [GraphQL::Language::Nodes::AbstractNode]
|
|
36
|
+
# @param definition [GraphQL::Schema::Field]
|
|
37
|
+
# @param parent_object [GraphQL::Schema::Object]
|
|
38
|
+
# @return [Hash{Symbol => Object}]
|
|
39
|
+
def arguments_for(ast_node, definition, parent_object: nil)
|
|
40
|
+
arguments_cache.fetch(ast_node, definition, parent_object)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def arguments_cache
|
|
44
|
+
@arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @api private
|
|
48
|
+
def handle_or_reraise(err)
|
|
49
|
+
@schema.handle_or_reraise(context, err)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
include Runnable
|
|
17
54
|
class OperationNameMissingError < GraphQL::ExecutionError
|
|
18
55
|
def initialize(name)
|
|
19
56
|
msg = if name.nil?
|
|
@@ -48,7 +85,7 @@ module GraphQL
|
|
|
48
85
|
# @return [GraphQL::StaticValidation::Validator] if present, the query will validate with these rules.
|
|
49
86
|
attr_reader :static_validator
|
|
50
87
|
|
|
51
|
-
# @param
|
|
88
|
+
# @param new_validator [GraphQL::StaticValidation::Validator] if present, the query will validate with these rules. This can't be reasssigned after validation.
|
|
52
89
|
def static_validator=(new_validator)
|
|
53
90
|
if defined?(@validation_pipeline) && @validation_pipeline && @validation_pipeline.has_validated?
|
|
54
91
|
raise ArgumentError, "Can't reassign Query#static_validator= after validation has run, remove this assignment."
|
|
@@ -95,41 +132,43 @@ module GraphQL
|
|
|
95
132
|
# @param root_value [Object] the object used to resolve fields on the root type
|
|
96
133
|
# @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value)
|
|
97
134
|
# @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
|
|
98
|
-
# @param
|
|
99
|
-
|
|
100
|
-
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil, warden: nil)
|
|
135
|
+
# @param visibility_profile [Symbol] Another way to assign `context[:visibility_profile]`
|
|
136
|
+
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, multiplex: nil, validate: true, static_validator: nil, visibility_profile: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil, use_visibility_profile: nil)
|
|
101
137
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
|
102
138
|
variables ||= {}
|
|
139
|
+
@multiplex = multiplex
|
|
103
140
|
@schema = schema
|
|
104
|
-
|
|
105
|
-
|
|
141
|
+
@context = schema.context_class.new(query: self, values: context)
|
|
142
|
+
if visibility_profile
|
|
143
|
+
@context[:visibility_profile] ||= visibility_profile
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if use_visibility_profile.nil?
|
|
147
|
+
use_visibility_profile = warden ? false : schema.use_visibility_profile?
|
|
106
148
|
end
|
|
107
|
-
|
|
108
|
-
|
|
149
|
+
|
|
150
|
+
if use_visibility_profile
|
|
151
|
+
@visibility_profile = @schema.visibility.profile_for(@context)
|
|
152
|
+
@warden = Schema::Warden::NullWarden.new(context: @context, schema: @schema)
|
|
153
|
+
else
|
|
154
|
+
@visibility_profile = nil
|
|
155
|
+
@warden = warden
|
|
156
|
+
end
|
|
157
|
+
|
|
109
158
|
@subscription_topic = subscription_topic
|
|
110
159
|
@root_value = root_value
|
|
111
160
|
@fragments = nil
|
|
112
161
|
@operations = nil
|
|
162
|
+
@finalizers = @top_level_finalizers = nil
|
|
113
163
|
@validate = validate
|
|
114
164
|
self.static_validator = static_validator if static_validator
|
|
115
165
|
context_tracers = (context ? context.fetch(:tracers, []) : [])
|
|
116
166
|
@tracers = schema.tracers + context_tracers
|
|
117
167
|
|
|
118
|
-
|
|
119
|
-
if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
|
|
120
|
-
if schema.trace_class <= GraphQL::Tracing::CallLegacyTracers
|
|
121
|
-
context_tracers += [GraphQL::Backtrace::Tracer]
|
|
122
|
-
@tracers << GraphQL::Backtrace::Tracer
|
|
123
|
-
elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
|
|
124
|
-
raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
|
|
168
|
+
if !context_tracers.empty? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
|
|
129
169
|
raise ArgumentError, "context[:tracers] are not supported without `trace_with(GraphQL::Tracing::CallLegacyTracers)` in the schema configuration, please add it."
|
|
130
170
|
end
|
|
131
171
|
|
|
132
|
-
|
|
133
172
|
@analysis_errors = []
|
|
134
173
|
if variables.is_a?(String)
|
|
135
174
|
raise ArgumentError, "Query variables should be a Hash, not a String. Try JSON.parse to prepare variables."
|
|
@@ -168,6 +207,8 @@ module GraphQL
|
|
|
168
207
|
|
|
169
208
|
@result_values = nil
|
|
170
209
|
@executed = false
|
|
210
|
+
|
|
211
|
+
@logger = schema.logger_for(context)
|
|
171
212
|
end
|
|
172
213
|
|
|
173
214
|
# If a document was provided to `GraphQL::Schema#execute` instead of the raw query string, we will need to get it from the document
|
|
@@ -175,9 +216,8 @@ module GraphQL
|
|
|
175
216
|
@query_string ||= (document ? document.to_query_string : nil)
|
|
176
217
|
end
|
|
177
218
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
end
|
|
219
|
+
# @return [Symbol, nil]
|
|
220
|
+
attr_reader :visibility_profile
|
|
181
221
|
|
|
182
222
|
attr_accessor :multiplex
|
|
183
223
|
|
|
@@ -194,9 +234,11 @@ module GraphQL
|
|
|
194
234
|
# @return [GraphQL::Execution::Lookahead]
|
|
195
235
|
def lookahead
|
|
196
236
|
@lookahead ||= begin
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
237
|
+
if selected_operation.nil?
|
|
238
|
+
GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
|
|
239
|
+
else
|
|
240
|
+
GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [selected_operation])
|
|
241
|
+
end
|
|
200
242
|
end
|
|
201
243
|
end
|
|
202
244
|
|
|
@@ -221,8 +263,28 @@ module GraphQL
|
|
|
221
263
|
with_prepared_ast { @operations }
|
|
222
264
|
end
|
|
223
265
|
|
|
266
|
+
def path
|
|
267
|
+
EmptyObjects::EMPTY_ARRAY
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Run subtree partials of this query and return their results.
|
|
271
|
+
# Each partial is identified with a `path:` and `object:`
|
|
272
|
+
# where the path references a field in the AST and the object will be treated
|
|
273
|
+
# as the return value from that field. Subfields of the field named by `path`
|
|
274
|
+
# will be executed with `object` as the starting point
|
|
275
|
+
# @param partials_hashes [Array<Hash{Symbol => Object}>] Hashes with `path:` and `object:` keys
|
|
276
|
+
# @return [Array<GraphQL::Query::Result>]
|
|
277
|
+
def run_partials(partials_hashes)
|
|
278
|
+
partials = partials_hashes.map { |partial_options| Partial.new(query: self, **partial_options) }
|
|
279
|
+
if context[:__graphql_execute_next]
|
|
280
|
+
Execution::Next.run_all(@schema, partials, context: @context)
|
|
281
|
+
else
|
|
282
|
+
Execution::Interpreter.run_all(@schema, partials, context: @context)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
224
286
|
# Get the result for this query, executing it once
|
|
225
|
-
# @return [
|
|
287
|
+
# @return [GraphQL::Query::Result] A Hash-like GraphQL response, with `"data"` and/or `"errors"` keys
|
|
226
288
|
def result
|
|
227
289
|
if !@executed
|
|
228
290
|
Execution::Interpreter.run_all(@schema, [self], context: @context)
|
|
@@ -263,19 +325,6 @@ module GraphQL
|
|
|
263
325
|
end
|
|
264
326
|
end
|
|
265
327
|
|
|
266
|
-
# Node-level cache for calculating arguments. Used during execution and query analysis.
|
|
267
|
-
# @param ast_node [GraphQL::Language::Nodes::AbstractNode]
|
|
268
|
-
# @param definition [GraphQL::Schema::Field]
|
|
269
|
-
# @param parent_object [GraphQL::Schema::Object]
|
|
270
|
-
# @return Hash{Symbol => Object}
|
|
271
|
-
def arguments_for(ast_node, definition, parent_object: nil)
|
|
272
|
-
arguments_cache.fetch(ast_node, definition, parent_object)
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
def arguments_cache
|
|
276
|
-
@arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
|
|
277
|
-
end
|
|
278
|
-
|
|
279
328
|
# A version of the given query string, with:
|
|
280
329
|
# - Variables inlined to the query
|
|
281
330
|
# - Strings replaced with `<REDACTED>`
|
|
@@ -304,7 +353,7 @@ module GraphQL
|
|
|
304
353
|
|
|
305
354
|
# @return [String] An opaque hash for identifying this query's given query string and selected operation
|
|
306
355
|
def operation_fingerprint
|
|
307
|
-
@operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string)}"
|
|
356
|
+
@operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string || "")}"
|
|
308
357
|
end
|
|
309
358
|
|
|
310
359
|
# @return [String] An opaque hash for identifying this query's given a variable values (not including defaults)
|
|
@@ -317,7 +366,7 @@ module GraphQL
|
|
|
317
366
|
end
|
|
318
367
|
|
|
319
368
|
def_delegators :validation_pipeline, :validation_errors,
|
|
320
|
-
:analyzers, :ast_analyzers, :max_depth, :max_complexity
|
|
369
|
+
:analyzers, :ast_analyzers, :max_depth, :max_complexity, :validate_timeout_remaining
|
|
321
370
|
|
|
322
371
|
attr_accessor :analysis_errors
|
|
323
372
|
def valid?
|
|
@@ -328,7 +377,38 @@ module GraphQL
|
|
|
328
377
|
with_prepared_ast { @warden }
|
|
329
378
|
end
|
|
330
379
|
|
|
331
|
-
|
|
380
|
+
def get_type(type_name)
|
|
381
|
+
types.type(type_name) # rubocop:disable Development/ContextIsPassedCop
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def get_field(owner, field_name)
|
|
385
|
+
types.field(owner, field_name) # rubocop:disable Development/ContextIsPassedCop
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def possible_types(type)
|
|
389
|
+
types.possible_types(type) # rubocop:disable Development/ContextIsPassedCop
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def root_type_for_operation(op_type)
|
|
393
|
+
case op_type
|
|
394
|
+
when "query", nil
|
|
395
|
+
types.query_root # rubocop:disable Development/ContextIsPassedCop
|
|
396
|
+
when "mutation"
|
|
397
|
+
types.mutation_root # rubocop:disable Development/ContextIsPassedCop
|
|
398
|
+
when "subscription"
|
|
399
|
+
types.subscription_root # rubocop:disable Development/ContextIsPassedCop
|
|
400
|
+
else
|
|
401
|
+
raise ArgumentError, "unexpected root type name: #{op_type.inspect}; expected nil, 'query', 'mutation', or 'subscription'"
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def root_type
|
|
406
|
+
root_type_for_operation(selected_operation.operation_type)
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
def types
|
|
410
|
+
@visibility_profile || warden.visibility_profile
|
|
411
|
+
end
|
|
332
412
|
|
|
333
413
|
# @param abstract_type [GraphQL::UnionType, GraphQL::InterfaceType]
|
|
334
414
|
# @param value [Object] Any runtime value
|
|
@@ -354,37 +434,11 @@ module GraphQL
|
|
|
354
434
|
with_prepared_ast { @query }
|
|
355
435
|
end
|
|
356
436
|
|
|
357
|
-
# @return [void]
|
|
358
|
-
def merge_filters(only: nil, except: nil)
|
|
359
|
-
if @prepared_ast
|
|
360
|
-
raise "Can't add filters after preparing the query"
|
|
361
|
-
else
|
|
362
|
-
@filter ||= @schema.default_filter
|
|
363
|
-
@filter = @filter.merge(only: only, except: except)
|
|
364
|
-
end
|
|
365
|
-
nil
|
|
366
|
-
end
|
|
367
|
-
|
|
368
437
|
def subscription?
|
|
369
438
|
with_prepared_ast { @subscription }
|
|
370
439
|
end
|
|
371
440
|
|
|
372
|
-
|
|
373
|
-
def handle_or_reraise(err)
|
|
374
|
-
schema.handle_or_reraise(context, err)
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
def after_lazy(value, &block)
|
|
378
|
-
if !defined?(@runtime_instance)
|
|
379
|
-
@runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
if @runtime_instance
|
|
383
|
-
@runtime_instance.minimal_after_lazy(value, &block)
|
|
384
|
-
else
|
|
385
|
-
@schema.after_lazy(value, &block)
|
|
386
|
-
end
|
|
387
|
-
end
|
|
441
|
+
attr_reader :logger
|
|
388
442
|
|
|
389
443
|
private
|
|
390
444
|
|
|
@@ -400,11 +454,11 @@ module GraphQL
|
|
|
400
454
|
|
|
401
455
|
def prepare_ast
|
|
402
456
|
@prepared_ast = true
|
|
403
|
-
@warden ||= @schema.warden_class.new(
|
|
457
|
+
@warden ||= @schema.warden_class.new(schema: @schema, context: @context)
|
|
404
458
|
parse_error = nil
|
|
405
459
|
@document ||= begin
|
|
406
460
|
if query_string
|
|
407
|
-
GraphQL.parse(query_string, trace: self.current_trace)
|
|
461
|
+
GraphQL.parse(query_string, trace: self.current_trace, max_tokens: @schema.max_query_string_tokens)
|
|
408
462
|
end
|
|
409
463
|
rescue GraphQL::ParseError => err
|
|
410
464
|
parse_error = err
|
|
@@ -436,7 +490,7 @@ module GraphQL
|
|
|
436
490
|
@mutation = false
|
|
437
491
|
@subscription = false
|
|
438
492
|
operation_name_error = nil
|
|
439
|
-
if
|
|
493
|
+
if !@operations.empty?
|
|
440
494
|
@selected_operation = find_operation(@operations, @operation_name)
|
|
441
495
|
if @selected_operation.nil?
|
|
442
496
|
operation_name_error = GraphQL::Query::OperationNameMissingError.new(@operation_name)
|
data/lib/graphql/railtie.rb
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module GraphQL
|
|
4
|
+
# Support {GraphQL::Parser::Cache} and {GraphQL.eager_load!}
|
|
5
|
+
#
|
|
6
|
+
# @example Enable the parser cache with default directory
|
|
7
|
+
#
|
|
8
|
+
# config.graphql.parser_cache = true
|
|
9
|
+
#
|
|
3
10
|
class Railtie < Rails::Railtie
|
|
4
|
-
config.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
config.graphql = ActiveSupport::OrderedOptions.new
|
|
12
|
+
config.graphql.parser_cache = false
|
|
13
|
+
config.eager_load_namespaces << GraphQL
|
|
14
|
+
|
|
15
|
+
initializer("graphql.cache") do |app|
|
|
16
|
+
if config.graphql.parser_cache
|
|
17
|
+
Language::Parser.cache ||= Language::Cache.new(
|
|
18
|
+
app.root.join("tmp/cache/graphql")
|
|
19
|
+
)
|
|
10
20
|
end
|
|
11
21
|
end
|
|
12
22
|
end
|
data/lib/graphql/rake_task.rb
CHANGED
|
@@ -9,8 +9,7 @@ module GraphQL
|
|
|
9
9
|
# By default, schemas are looked up by name as constants using `schema_name:`.
|
|
10
10
|
# You can provide a `load_schema` function to return your schema another way.
|
|
11
11
|
#
|
|
12
|
-
# `load_context
|
|
13
|
-
# you can keep an eye on how filters affect your schema.
|
|
12
|
+
# Use `load_context:` and `visible?` to dump schemas under certain visibility constraints.
|
|
14
13
|
#
|
|
15
14
|
# @example Dump a Schema to .graphql + .json files
|
|
16
15
|
# require "graphql/rake_task"
|
|
@@ -36,8 +35,6 @@ module GraphQL
|
|
|
36
35
|
schema_name: nil,
|
|
37
36
|
load_schema: ->(task) { Object.const_get(task.schema_name) },
|
|
38
37
|
load_context: ->(task) { {} },
|
|
39
|
-
only: nil,
|
|
40
|
-
except: nil,
|
|
41
38
|
directory: ".",
|
|
42
39
|
idl_outfile: "schema.graphql",
|
|
43
40
|
json_outfile: "schema.json",
|
|
@@ -68,12 +65,6 @@ module GraphQL
|
|
|
68
65
|
# @return [<#call(task)>] A callable for loading the query context
|
|
69
66
|
attr_accessor :load_context
|
|
70
67
|
|
|
71
|
-
# @return [<#call(member, ctx)>, nil] A filter for this task
|
|
72
|
-
attr_accessor :only
|
|
73
|
-
|
|
74
|
-
# @return [<#call(member, ctx)>, nil] A filter for this task
|
|
75
|
-
attr_accessor :except
|
|
76
|
-
|
|
77
68
|
# @return [String] target for IDL task
|
|
78
69
|
attr_accessor :idl_outfile
|
|
79
70
|
|
|
@@ -117,10 +108,10 @@ module GraphQL
|
|
|
117
108
|
include_is_repeatable: include_is_repeatable,
|
|
118
109
|
include_specified_by_url: include_specified_by_url,
|
|
119
110
|
include_schema_description: include_schema_description,
|
|
120
|
-
|
|
111
|
+
context: context
|
|
121
112
|
)
|
|
122
113
|
when :to_definition
|
|
123
|
-
schema.to_definition(
|
|
114
|
+
schema.to_definition(context: context)
|
|
124
115
|
else
|
|
125
116
|
raise ArgumentError, "Unexpected schema dump method: #{method_name.inspect}"
|
|
126
117
|
end
|
|
@@ -9,7 +9,7 @@ module GraphQL
|
|
|
9
9
|
|
|
10
10
|
# Return the source of `send_node`, but without the keyword argument represented by `pair_node`
|
|
11
11
|
def source_without_keyword_argument(send_node, pair_node)
|
|
12
|
-
# work back to the
|
|
12
|
+
# work back to the preceding comma
|
|
13
13
|
first_pos = pair_node.location.expression.begin_pos
|
|
14
14
|
end_pos = pair_node.location.expression.end_pos
|
|
15
15
|
node_source = send_node.source_range.source
|