graphql 2.0.32 → 2.5.22
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 +95 -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/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- 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 +363 -434
- data/lib/graphql/execution/interpreter.rb +91 -164
- data/lib/graphql/execution/lookahead.rb +105 -31
- data/lib/graphql/execution/multiplex.rb +7 -6
- data/lib/graphql/execution/next/field_resolve_step.rb +711 -0
- data/lib/graphql/execution/next/load_argument_step.rb +60 -0
- data/lib/graphql/execution/next/prepare_object_step.rb +129 -0
- data/lib/graphql/execution/next/runner.rb +389 -0
- data/lib/graphql/execution/next/selections_step.rb +37 -0
- data/lib/graphql/execution/next.rb +70 -0
- data/lib/graphql/execution.rb +1 -0
- data/lib/graphql/execution_error.rb +13 -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 +319 -193
- data/lib/graphql/language/nodes.rb +136 -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 +23 -83
- 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 +82 -144
- data/lib/graphql/query/null_context.rb +15 -18
- data/lib/graphql/query/partial.rb +179 -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 +126 -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/schema/addition.rb +26 -13
- data/lib/graphql/schema/always_visible.rb +7 -2
- data/lib/graphql/schema/argument.rb +75 -9
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +123 -60
- 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 +54 -2
- data/lib/graphql/schema/enum.rb +110 -27
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +15 -49
- data/lib/graphql/schema/field/scope_extension.rb +23 -7
- data/lib/graphql/schema/field.rb +245 -118
- data/lib/graphql/schema/field_extension.rb +34 -1
- data/lib/graphql/schema/has_single_input_argument.rb +160 -0
- data/lib/graphql/schema/input_object.rb +116 -60
- data/lib/graphql/schema/interface.rb +34 -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 +3 -3
- data/lib/graphql/schema/loader.rb +3 -4
- data/lib/graphql/schema/member/base_dsl_methods.rb +18 -2
- 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 +4 -4
- data/lib/graphql/schema/member/has_fields.rb +115 -15
- data/lib/graphql/schema/member/has_interfaces.rb +26 -12
- 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 +17 -4
- 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/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 +90 -32
- data/lib/graphql/schema/scalar.rb +4 -9
- data/lib/graphql/schema/subscription.rb +63 -10
- 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 +445 -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.rb +950 -210
- data/lib/graphql/static_validation/all_rules.rb +3 -3
- data/lib/graphql/static_validation/base_visitor.rb +7 -6
- data/lib/graphql/static_validation/literal_validator.rb +6 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -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 +12 -2
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +47 -13
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +88 -25
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -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 +5 -5
- 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 +11 -2
- data/lib/graphql/static_validation/validation_context.rb +21 -5
- 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 +12 -10
- data/lib/graphql/subscriptions/event.rb +21 -4
- data/lib/graphql/subscriptions/serialize.rb +3 -1
- data/lib/graphql/subscriptions.rb +21 -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 +7 -3
- data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
- data/lib/graphql/tracing/appsignal_trace.rb +32 -59
- 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 -162
- 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 +183 -37
- 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_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
- data/lib/graphql/tracing/prometheus_trace.rb +73 -73
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -58
- 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 -45
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +112 -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 +44 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +18 -0
- 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 +5 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +71 -54
- data/readme.md +12 -2
- metadata +233 -37
- 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
|
@@ -40,7 +40,7 @@ module GraphQL
|
|
|
40
40
|
case node
|
|
41
41
|
when FalseClass, Float, Integer, String, TrueClass
|
|
42
42
|
if @current_argument && redact_argument_value?(@current_argument, node)
|
|
43
|
-
redacted_argument_value(@current_argument)
|
|
43
|
+
print_string(redacted_argument_value(@current_argument))
|
|
44
44
|
else
|
|
45
45
|
super
|
|
46
46
|
end
|
|
@@ -51,9 +51,8 @@ module GraphQL
|
|
|
51
51
|
@current_input_type = @current_input_type.of_type if @current_input_type.non_null?
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
super
|
|
55
55
|
@current_input_type = old_input_type
|
|
56
|
-
res
|
|
57
56
|
else
|
|
58
57
|
super
|
|
59
58
|
end
|
|
@@ -89,11 +88,12 @@ module GraphQL
|
|
|
89
88
|
else
|
|
90
89
|
argument.value
|
|
91
90
|
end
|
|
92
|
-
|
|
91
|
+
|
|
92
|
+
print_string("#{argument.name}: ")
|
|
93
|
+
print_node(argument_value)
|
|
93
94
|
|
|
94
95
|
@current_input_type = old_input_type
|
|
95
96
|
@current_argument = old_current_argument
|
|
96
|
-
res
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def coerce_argument_value_to_list?(type, value)
|
|
@@ -113,12 +113,11 @@ module GraphQL
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
def print_field(field, indent: "")
|
|
116
|
-
@current_field = query.
|
|
116
|
+
@current_field = query.types.field(@current_type, field.name)
|
|
117
117
|
old_type = @current_type
|
|
118
118
|
@current_type = @current_field.type.unwrap
|
|
119
|
-
|
|
119
|
+
super
|
|
120
120
|
@current_type = old_type
|
|
121
|
-
res
|
|
122
121
|
end
|
|
123
122
|
|
|
124
123
|
def print_inline_fragment(inline_fragment, indent: "")
|
|
@@ -128,31 +127,26 @@ module GraphQL
|
|
|
128
127
|
@current_type = query.get_type(inline_fragment.type.name)
|
|
129
128
|
end
|
|
130
129
|
|
|
131
|
-
|
|
130
|
+
super
|
|
132
131
|
|
|
133
132
|
@current_type = old_type
|
|
134
|
-
|
|
135
|
-
res
|
|
136
133
|
end
|
|
137
134
|
|
|
138
135
|
def print_fragment_definition(fragment_def, indent: "")
|
|
139
136
|
old_type = @current_type
|
|
140
137
|
@current_type = query.get_type(fragment_def.type.name)
|
|
141
138
|
|
|
142
|
-
|
|
139
|
+
super
|
|
143
140
|
|
|
144
141
|
@current_type = old_type
|
|
145
|
-
|
|
146
|
-
res
|
|
147
142
|
end
|
|
148
143
|
|
|
149
144
|
def print_directive(directive)
|
|
150
145
|
@current_directive = query.schema.directives[directive.name]
|
|
151
146
|
|
|
152
|
-
|
|
147
|
+
super
|
|
153
148
|
|
|
154
149
|
@current_directive = nil
|
|
155
|
-
res
|
|
156
150
|
end
|
|
157
151
|
|
|
158
152
|
# Print the operation definition but do not include the variable
|
|
@@ -162,16 +156,15 @@ module GraphQL
|
|
|
162
156
|
@current_type = query.schema.public_send(operation_definition.operation_type)
|
|
163
157
|
|
|
164
158
|
if @inline_variables
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
print_string("#{indent}#{operation_definition.operation_type}")
|
|
160
|
+
print_string(" #{operation_definition.name}") if operation_definition.name
|
|
161
|
+
print_directives(operation_definition.directives)
|
|
162
|
+
print_selections(operation_definition.selections, indent: indent)
|
|
169
163
|
else
|
|
170
|
-
|
|
164
|
+
super
|
|
171
165
|
end
|
|
172
166
|
|
|
173
167
|
@current_type = old_type
|
|
174
|
-
out
|
|
175
168
|
end
|
|
176
169
|
|
|
177
170
|
private
|
|
@@ -210,7 +203,12 @@ module GraphQL
|
|
|
210
203
|
[value].map { |v| value_to_ast(v, type.of_type) }
|
|
211
204
|
end
|
|
212
205
|
when "ENUM"
|
|
213
|
-
GraphQL::Language::Nodes::Enum
|
|
206
|
+
if value.is_a?(GraphQL::Language::Nodes::Enum)
|
|
207
|
+
# if it was a default value, it's already wrapped
|
|
208
|
+
value
|
|
209
|
+
else
|
|
210
|
+
GraphQL::Language::Nodes::Enum.new(name: value)
|
|
211
|
+
end
|
|
214
212
|
else
|
|
215
213
|
value
|
|
216
214
|
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module GraphQL
|
|
3
|
+
module Language
|
|
4
|
+
# Like `GraphQL::Language::Visitor` except it doesn't support
|
|
5
|
+
# making changes to the document -- only visiting it as-is.
|
|
6
|
+
class StaticVisitor
|
|
7
|
+
def initialize(document)
|
|
8
|
+
@document = document
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Visit `document` and all children
|
|
12
|
+
# @return [void]
|
|
13
|
+
def visit
|
|
14
|
+
# `@document` may be any kind of node:
|
|
15
|
+
visit_method = @document.visit_method
|
|
16
|
+
result = public_send(visit_method, @document, nil)
|
|
17
|
+
@result = if result.is_a?(Array)
|
|
18
|
+
result.first
|
|
19
|
+
else
|
|
20
|
+
# The node wasn't modified
|
|
21
|
+
@document
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def on_document_children(document_node)
|
|
26
|
+
document_node.children.each do |child_node|
|
|
27
|
+
visit_method = child_node.visit_method
|
|
28
|
+
public_send(visit_method, child_node, document_node)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def on_field_children(new_node)
|
|
33
|
+
new_node.arguments.each do |arg_node| # rubocop:disable Development/ContextIsPassedCop
|
|
34
|
+
on_argument(arg_node, new_node)
|
|
35
|
+
end
|
|
36
|
+
visit_directives(new_node)
|
|
37
|
+
visit_selections(new_node)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def visit_directives(new_node)
|
|
41
|
+
new_node.directives.each do |dir_node|
|
|
42
|
+
on_directive(dir_node, new_node)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def visit_selections(new_node)
|
|
47
|
+
new_node.selections.each do |selection|
|
|
48
|
+
case selection
|
|
49
|
+
when GraphQL::Language::Nodes::Field
|
|
50
|
+
on_field(selection, new_node)
|
|
51
|
+
when GraphQL::Language::Nodes::InlineFragment
|
|
52
|
+
on_inline_fragment(selection, new_node)
|
|
53
|
+
when GraphQL::Language::Nodes::FragmentSpread
|
|
54
|
+
on_fragment_spread(selection, new_node)
|
|
55
|
+
else
|
|
56
|
+
raise ArgumentError, "Invariant: unexpected field selection #{selection.class} (#{selection.inspect})"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def on_fragment_definition_children(new_node)
|
|
62
|
+
visit_directives(new_node)
|
|
63
|
+
visit_selections(new_node)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
alias :on_inline_fragment_children :on_fragment_definition_children
|
|
67
|
+
|
|
68
|
+
def on_operation_definition_children(new_node)
|
|
69
|
+
new_node.variables.each do |arg_node|
|
|
70
|
+
on_variable_definition(arg_node, new_node)
|
|
71
|
+
end
|
|
72
|
+
visit_directives(new_node)
|
|
73
|
+
visit_selections(new_node)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def on_argument_children(new_node)
|
|
77
|
+
new_node.children.each do |value_node|
|
|
78
|
+
case value_node
|
|
79
|
+
when Language::Nodes::VariableIdentifier
|
|
80
|
+
on_variable_identifier(value_node, new_node)
|
|
81
|
+
when Language::Nodes::InputObject
|
|
82
|
+
on_input_object(value_node, new_node)
|
|
83
|
+
when Language::Nodes::Enum
|
|
84
|
+
on_enum(value_node, new_node)
|
|
85
|
+
when Language::Nodes::NullValue
|
|
86
|
+
on_null_value(value_node, new_node)
|
|
87
|
+
else
|
|
88
|
+
raise ArgumentError, "Invariant: unexpected argument value node #{value_node.class} (#{value_node.inspect})"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
|
94
|
+
|
|
95
|
+
# We don't use `alias` here because it breaks `super`
|
|
96
|
+
def self.make_visit_methods(ast_node_class)
|
|
97
|
+
node_method = ast_node_class.visit_method
|
|
98
|
+
children_of_type = ast_node_class.children_of_type
|
|
99
|
+
child_visit_method = :"#{node_method}_children"
|
|
100
|
+
|
|
101
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
|
102
|
+
# The default implementation for visiting an AST node.
|
|
103
|
+
# It doesn't _do_ anything, but it continues to visiting the node's children.
|
|
104
|
+
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
|
105
|
+
# in your subclasses.
|
|
106
|
+
#
|
|
107
|
+
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
|
108
|
+
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
|
109
|
+
# @return [void]
|
|
110
|
+
def #{node_method}(node, parent)
|
|
111
|
+
#{
|
|
112
|
+
if method_defined?(child_visit_method)
|
|
113
|
+
"#{child_visit_method}(node)"
|
|
114
|
+
elsif children_of_type
|
|
115
|
+
children_of_type.map do |child_accessor, child_class|
|
|
116
|
+
"node.#{child_accessor}.each do |child_node|
|
|
117
|
+
#{child_class.visit_method}(child_node, node)
|
|
118
|
+
end"
|
|
119
|
+
end.join("\n")
|
|
120
|
+
else
|
|
121
|
+
""
|
|
122
|
+
end
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
RUBY
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
[
|
|
129
|
+
Language::Nodes::Argument,
|
|
130
|
+
Language::Nodes::Directive,
|
|
131
|
+
Language::Nodes::DirectiveDefinition,
|
|
132
|
+
Language::Nodes::DirectiveLocation,
|
|
133
|
+
Language::Nodes::Document,
|
|
134
|
+
Language::Nodes::Enum,
|
|
135
|
+
Language::Nodes::EnumTypeDefinition,
|
|
136
|
+
Language::Nodes::EnumTypeExtension,
|
|
137
|
+
Language::Nodes::EnumValueDefinition,
|
|
138
|
+
Language::Nodes::Field,
|
|
139
|
+
Language::Nodes::FieldDefinition,
|
|
140
|
+
Language::Nodes::FragmentDefinition,
|
|
141
|
+
Language::Nodes::FragmentSpread,
|
|
142
|
+
Language::Nodes::InlineFragment,
|
|
143
|
+
Language::Nodes::InputObject,
|
|
144
|
+
Language::Nodes::InputObjectTypeDefinition,
|
|
145
|
+
Language::Nodes::InputObjectTypeExtension,
|
|
146
|
+
Language::Nodes::InputValueDefinition,
|
|
147
|
+
Language::Nodes::InterfaceTypeDefinition,
|
|
148
|
+
Language::Nodes::InterfaceTypeExtension,
|
|
149
|
+
Language::Nodes::ListType,
|
|
150
|
+
Language::Nodes::NonNullType,
|
|
151
|
+
Language::Nodes::NullValue,
|
|
152
|
+
Language::Nodes::ObjectTypeDefinition,
|
|
153
|
+
Language::Nodes::ObjectTypeExtension,
|
|
154
|
+
Language::Nodes::OperationDefinition,
|
|
155
|
+
Language::Nodes::ScalarTypeDefinition,
|
|
156
|
+
Language::Nodes::ScalarTypeExtension,
|
|
157
|
+
Language::Nodes::SchemaDefinition,
|
|
158
|
+
Language::Nodes::SchemaExtension,
|
|
159
|
+
Language::Nodes::TypeName,
|
|
160
|
+
Language::Nodes::UnionTypeDefinition,
|
|
161
|
+
Language::Nodes::UnionTypeExtension,
|
|
162
|
+
Language::Nodes::VariableDefinition,
|
|
163
|
+
Language::Nodes::VariableIdentifier,
|
|
164
|
+
].each do |ast_node_class|
|
|
165
|
+
make_visit_methods(ast_node_class)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# rubocop:disable Development/NoEvalCop
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
@@ -30,12 +30,9 @@ module GraphQL
|
|
|
30
30
|
# # Check the result
|
|
31
31
|
# visitor.count
|
|
32
32
|
# # => 3
|
|
33
|
+
#
|
|
34
|
+
# @see GraphQL::Language::StaticVisitor for a faster visitor that doesn't support modifying the document
|
|
33
35
|
class Visitor
|
|
34
|
-
# If any hook returns this value, the {Visitor} stops visiting this
|
|
35
|
-
# node right away
|
|
36
|
-
# @deprecated Use `super` to continue the visit; or don't call it to halt.
|
|
37
|
-
SKIP = :_skip
|
|
38
|
-
|
|
39
36
|
class DeleteNode; end
|
|
40
37
|
|
|
41
38
|
# When this is returned from a visitor method,
|
|
@@ -44,25 +41,13 @@ module GraphQL
|
|
|
44
41
|
|
|
45
42
|
def initialize(document)
|
|
46
43
|
@document = document
|
|
47
|
-
@visitors = {}
|
|
48
44
|
@result = nil
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
# @return [GraphQL::Language::Nodes::Document] The document with any modifications applied
|
|
52
48
|
attr_reader :result
|
|
53
49
|
|
|
54
|
-
#
|
|
55
|
-
# @param node_class [Class] The node class that you want to listen to
|
|
56
|
-
# @return [NodeVisitor]
|
|
57
|
-
#
|
|
58
|
-
# @example Run a hook whenever you enter a new Field
|
|
59
|
-
# visitor[GraphQL::Language::Nodes::Field] << ->(node, parent) { p "Here's a field" }
|
|
60
|
-
# @deprecated see `on_` methods, like {#on_field}
|
|
61
|
-
def [](node_class)
|
|
62
|
-
@visitors[node_class] ||= NodeVisitor.new
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Visit `document` and all children, applying hooks as you go
|
|
50
|
+
# Visit `document` and all children
|
|
66
51
|
# @return [void]
|
|
67
52
|
def visit
|
|
68
53
|
# `@document` may be any kind of node:
|
|
@@ -178,6 +163,7 @@ module GraphQL
|
|
|
178
163
|
|
|
179
164
|
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
|
180
165
|
|
|
166
|
+
# We don't use `alias` here because it breaks `super`
|
|
181
167
|
def self.make_visit_methods(ast_node_class)
|
|
182
168
|
node_method = ast_node_class.visit_method
|
|
183
169
|
children_of_type = ast_node_class.children_of_type
|
|
@@ -189,7 +175,6 @@ module GraphQL
|
|
|
189
175
|
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
|
190
176
|
# in your subclasses.
|
|
191
177
|
#
|
|
192
|
-
# For compatibility, it calls hook procs, too.
|
|
193
178
|
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
|
194
179
|
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
|
195
180
|
# @return [Array, nil] If there were modifications, it returns an array of new nodes, otherwise, it returns `nil`.
|
|
@@ -199,29 +184,25 @@ module GraphQL
|
|
|
199
184
|
# by a user hook, don't want to keep visiting in that case.
|
|
200
185
|
[node, parent]
|
|
201
186
|
else
|
|
202
|
-
# Run hooks if there are any
|
|
203
187
|
new_node = node
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
end
|
|
224
|
-
end_visit(new_node, parent) unless no_hooks
|
|
188
|
+
#{
|
|
189
|
+
if method_defined?(child_visit_method)
|
|
190
|
+
"new_node = #{child_visit_method}(new_node)"
|
|
191
|
+
elsif children_of_type
|
|
192
|
+
children_of_type.map do |child_accessor, child_class|
|
|
193
|
+
"node.#{child_accessor}.each do |child_node|
|
|
194
|
+
new_child_and_node = #{child_class.visit_method}_with_modifications(child_node, new_node)
|
|
195
|
+
# Reassign `node` in case the child hook makes a modification
|
|
196
|
+
if new_child_and_node.is_a?(Array)
|
|
197
|
+
new_node = new_child_and_node[1]
|
|
198
|
+
end
|
|
199
|
+
end"
|
|
200
|
+
end.join("\n")
|
|
201
|
+
else
|
|
202
|
+
""
|
|
203
|
+
end
|
|
204
|
+
}
|
|
205
|
+
|
|
225
206
|
if new_node.equal?(node)
|
|
226
207
|
[node, parent]
|
|
227
208
|
else
|
|
@@ -229,6 +210,7 @@ module GraphQL
|
|
|
229
210
|
end
|
|
230
211
|
end
|
|
231
212
|
end
|
|
213
|
+
|
|
232
214
|
def #{node_method}_with_modifications(node, parent)
|
|
233
215
|
new_node_and_new_parent = #{node_method}(node, parent)
|
|
234
216
|
apply_modifications(node, parent, new_node_and_new_parent)
|
|
@@ -236,8 +218,6 @@ module GraphQL
|
|
|
236
218
|
RUBY
|
|
237
219
|
end
|
|
238
220
|
|
|
239
|
-
|
|
240
|
-
|
|
241
221
|
[
|
|
242
222
|
Language::Nodes::Argument,
|
|
243
223
|
Language::Nodes::Directive,
|
|
@@ -308,46 +288,6 @@ module GraphQL
|
|
|
308
288
|
new_node_and_new_parent
|
|
309
289
|
end
|
|
310
290
|
end
|
|
311
|
-
|
|
312
|
-
def begin_visit(node, parent)
|
|
313
|
-
node_visitor = self[node.class]
|
|
314
|
-
self.class.apply_hooks(node_visitor.enter, node, parent)
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
# Should global `leave` visitors come first or last?
|
|
318
|
-
def end_visit(node, parent)
|
|
319
|
-
node_visitor = self[node.class]
|
|
320
|
-
self.class.apply_hooks(node_visitor.leave, node, parent)
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
# If one of the visitors returns SKIP, stop visiting this node
|
|
324
|
-
def self.apply_hooks(hooks, node, parent)
|
|
325
|
-
hooks.each do |proc|
|
|
326
|
-
return false if proc.call(node, parent) == SKIP
|
|
327
|
-
end
|
|
328
|
-
true
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# Collect `enter` and `leave` hooks for classes in {GraphQL::Language::Nodes}
|
|
332
|
-
#
|
|
333
|
-
# Access {NodeVisitor}s via {GraphQL::Language::Visitor#[]}
|
|
334
|
-
class NodeVisitor
|
|
335
|
-
# @return [Array<Proc>] Hooks to call when entering a node of this type
|
|
336
|
-
attr_reader :enter
|
|
337
|
-
# @return [Array<Proc>] Hooks to call when leaving a node of this type
|
|
338
|
-
attr_reader :leave
|
|
339
|
-
|
|
340
|
-
def initialize
|
|
341
|
-
@enter = []
|
|
342
|
-
@leave = []
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
# Shorthand to add a hook to the {#enter} array
|
|
346
|
-
# @param hook [Proc] A hook to add
|
|
347
|
-
def <<(hook)
|
|
348
|
-
enter << hook
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
291
|
end
|
|
352
292
|
end
|
|
353
293
|
end
|
data/lib/graphql/language.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require "graphql/language/block_string"
|
|
3
|
+
require "graphql/language/comment"
|
|
3
4
|
require "graphql/language/printer"
|
|
4
5
|
require "graphql/language/sanitized_printer"
|
|
5
6
|
require "graphql/language/document_from_schema_definition"
|
|
@@ -8,9 +9,10 @@ require "graphql/language/lexer"
|
|
|
8
9
|
require "graphql/language/nodes"
|
|
9
10
|
require "graphql/language/cache"
|
|
10
11
|
require "graphql/language/parser"
|
|
11
|
-
require "graphql/language/
|
|
12
|
+
require "graphql/language/static_visitor"
|
|
12
13
|
require "graphql/language/visitor"
|
|
13
14
|
require "graphql/language/definition_slice"
|
|
15
|
+
require "strscan"
|
|
14
16
|
|
|
15
17
|
module GraphQL
|
|
16
18
|
module Language
|
|
@@ -31,6 +33,74 @@ module GraphQL
|
|
|
31
33
|
else
|
|
32
34
|
JSON.generate(value, quirks_mode: true)
|
|
33
35
|
end
|
|
36
|
+
rescue JSON::GeneratorError
|
|
37
|
+
if Float::INFINITY == value
|
|
38
|
+
"Infinity"
|
|
39
|
+
else
|
|
40
|
+
raise
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns a new string if any single-quoted newlines were escaped.
|
|
45
|
+
# Otherwise, returns `query_str` unchanged.
|
|
46
|
+
# @return [String]
|
|
47
|
+
def self.escape_single_quoted_newlines(query_str)
|
|
48
|
+
scanner = StringScanner.new(query_str)
|
|
49
|
+
inside_single_quoted_string = false
|
|
50
|
+
new_query_str = nil
|
|
51
|
+
while !scanner.eos?
|
|
52
|
+
if scanner.skip(/(?:\\"|[^"\n\r]|""")+/m)
|
|
53
|
+
new_query_str && (new_query_str << scanner.matched)
|
|
54
|
+
elsif scanner.skip('"')
|
|
55
|
+
new_query_str && (new_query_str << '"')
|
|
56
|
+
inside_single_quoted_string = !inside_single_quoted_string
|
|
57
|
+
elsif scanner.skip("\n")
|
|
58
|
+
if inside_single_quoted_string
|
|
59
|
+
new_query_str ||= query_str[0, scanner.pos - 1]
|
|
60
|
+
new_query_str << '\\n'
|
|
61
|
+
else
|
|
62
|
+
new_query_str && (new_query_str << "\n")
|
|
63
|
+
end
|
|
64
|
+
elsif scanner.skip("\r")
|
|
65
|
+
if inside_single_quoted_string
|
|
66
|
+
new_query_str ||= query_str[0, scanner.pos - 1]
|
|
67
|
+
new_query_str << '\\r'
|
|
68
|
+
else
|
|
69
|
+
new_query_str && (new_query_str << "\r")
|
|
70
|
+
end
|
|
71
|
+
elsif scanner.eos?
|
|
72
|
+
break
|
|
73
|
+
else
|
|
74
|
+
raise ArgumentError, "Unmatchable string scanner segment: #{scanner.rest.inspect}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
new_query_str || query_str
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
LEADING_REGEX = Regexp.union(" ", *Lexer::Punctuation.constants.map { |const| Lexer::Punctuation.const_get(const) })
|
|
81
|
+
|
|
82
|
+
# Optimized pattern using:
|
|
83
|
+
# - Possessive quantifiers (*+, ++) to prevent backtracking in number patterns
|
|
84
|
+
# - Atomic group (?>...) for IGNORE to prevent backtracking
|
|
85
|
+
# - Single unified number pattern instead of three alternatives
|
|
86
|
+
EFFICIENT_NUMBER_REGEXP = /-?(?:0|[1-9][0-9]*+)(?:\.[0-9]++)?(?:[eE][+-]?[0-9]++)?/
|
|
87
|
+
EFFICIENT_IGNORE_REGEXP = /(?>[, \r\n\t]+|\#[^\n]*$)*/
|
|
88
|
+
|
|
89
|
+
MAYBE_INVALID_NUMBER = /\d[_a-zA-Z]/
|
|
90
|
+
|
|
91
|
+
INVALID_NUMBER_FOLLOWED_BY_NAME_REGEXP = %r{
|
|
92
|
+
(?<leading>#{LEADING_REGEX})
|
|
93
|
+
(?<num>#{EFFICIENT_NUMBER_REGEXP})
|
|
94
|
+
(?<name>#{Lexer::IDENTIFIER_REGEXP})
|
|
95
|
+
#{EFFICIENT_IGNORE_REGEXP}
|
|
96
|
+
:
|
|
97
|
+
}x
|
|
98
|
+
|
|
99
|
+
def self.add_space_between_numbers_and_names(query_str)
|
|
100
|
+
# Fast check for digit followed by identifier char. If this doesn't match, skip the more expensive regexp entirely.
|
|
101
|
+
return query_str unless query_str.match?(MAYBE_INVALID_NUMBER)
|
|
102
|
+
return query_str unless query_str.match?(INVALID_NUMBER_FOLLOWED_BY_NAME_REGEXP)
|
|
103
|
+
query_str.gsub(INVALID_NUMBER_FOLLOWED_BY_NAME_REGEXP, "\\k<leading>\\k<num> \\k<name>:")
|
|
34
104
|
end
|
|
35
105
|
end
|
|
36
106
|
end
|
|
@@ -12,10 +12,14 @@ module GraphQL
|
|
|
12
12
|
attr_reader :id
|
|
13
13
|
# @return [Object] The value found with this ID
|
|
14
14
|
attr_reader :object
|
|
15
|
-
|
|
15
|
+
# @return [GraphQL::Query::Context]
|
|
16
|
+
attr_reader :context
|
|
17
|
+
|
|
18
|
+
def initialize(argument:, id:, object:, context:)
|
|
16
19
|
@id = id
|
|
17
20
|
@argument = argument
|
|
18
21
|
@object = object
|
|
22
|
+
@context = context
|
|
19
23
|
super("No object found for `#{argument.graphql_name}: #{id.inspect}`")
|
|
20
24
|
end
|
|
21
25
|
end
|
|
@@ -35,10 +35,10 @@ module GraphQL
|
|
|
35
35
|
def load_nodes
|
|
36
36
|
@nodes ||= begin
|
|
37
37
|
sliced_nodes = if before && after
|
|
38
|
-
end_idx = index_from_cursor(before)-
|
|
38
|
+
end_idx = index_from_cursor(before) - 2
|
|
39
39
|
end_idx < 0 ? [] : items[index_from_cursor(after)..end_idx] || []
|
|
40
40
|
elsif before
|
|
41
|
-
end_idx = index_from_cursor(before)-2
|
|
41
|
+
end_idx = index_from_cursor(before) - 2
|
|
42
42
|
end_idx < 0 ? [] : items[0..end_idx] || []
|
|
43
43
|
elsif after
|
|
44
44
|
items[index_from_cursor(after)..-1] || []
|
|
@@ -56,12 +56,12 @@ module GraphQL
|
|
|
56
56
|
false
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
@has_next_page = if
|
|
60
|
-
# There are more items after these items
|
|
61
|
-
sliced_nodes.count > first
|
|
62
|
-
elsif before
|
|
59
|
+
@has_next_page = if before
|
|
63
60
|
# The original array is longer than the `before` index
|
|
64
61
|
index_from_cursor(before) < items.length + 1
|
|
62
|
+
elsif first
|
|
63
|
+
# There are more items after these items
|
|
64
|
+
sliced_nodes.count > first
|
|
65
65
|
else
|
|
66
66
|
false
|
|
67
67
|
end
|
|
@@ -19,7 +19,15 @@ module GraphQL
|
|
|
19
19
|
attr_reader :items
|
|
20
20
|
|
|
21
21
|
# @return [GraphQL::Query::Context]
|
|
22
|
-
|
|
22
|
+
attr_reader :context
|
|
23
|
+
|
|
24
|
+
def context=(new_ctx)
|
|
25
|
+
@context = new_ctx
|
|
26
|
+
if @was_authorized_by_scope_items.nil?
|
|
27
|
+
@was_authorized_by_scope_items = detect_was_authorized_by_scope_items
|
|
28
|
+
end
|
|
29
|
+
@context
|
|
30
|
+
end
|
|
23
31
|
|
|
24
32
|
# @return [Object] the object this collection belongs to
|
|
25
33
|
attr_accessor :parent
|
|
@@ -83,6 +91,13 @@ module GraphQL
|
|
|
83
91
|
else
|
|
84
92
|
default_page_size
|
|
85
93
|
end
|
|
94
|
+
@was_authorized_by_scope_items = detect_was_authorized_by_scope_items
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
attr_writer :was_authorized_by_scope_items
|
|
98
|
+
|
|
99
|
+
def was_authorized_by_scope_items?
|
|
100
|
+
@was_authorized_by_scope_items
|
|
86
101
|
end
|
|
87
102
|
|
|
88
103
|
def max_page_size=(new_value)
|
|
@@ -208,6 +223,16 @@ module GraphQL
|
|
|
208
223
|
|
|
209
224
|
private
|
|
210
225
|
|
|
226
|
+
def detect_was_authorized_by_scope_items
|
|
227
|
+
if @context &&
|
|
228
|
+
(current_runtime_state = Fiber[:__graphql_runtime_info]) &&
|
|
229
|
+
(query_runtime_state = current_runtime_state[@context.query])
|
|
230
|
+
query_runtime_state.was_authorized_by_scope_items
|
|
231
|
+
else
|
|
232
|
+
nil
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
211
236
|
# @param argument [nil, Integer] `first` or `last`, as provided by the client
|
|
212
237
|
# @param max_page_size [nil, Integer]
|
|
213
238
|
# @return [nil, Integer] `nil` if the input was `nil`, otherwise a value between `0` and `max_page_size`
|
|
@@ -247,6 +272,10 @@ module GraphQL
|
|
|
247
272
|
def cursor
|
|
248
273
|
@cursor ||= @connection.cursor_for(@node)
|
|
249
274
|
end
|
|
275
|
+
|
|
276
|
+
def was_authorized_by_scope_items?
|
|
277
|
+
@connection.was_authorized_by_scope_items?
|
|
278
|
+
end
|
|
250
279
|
end
|
|
251
280
|
end
|
|
252
281
|
end
|