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,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative "./base_cop"
|
|
3
|
+
|
|
4
|
+
module GraphQL
|
|
5
|
+
module Rubocop
|
|
6
|
+
module GraphQL
|
|
7
|
+
# Identify (and auto-correct) any field whose type configuration isn't given
|
|
8
|
+
# in the configuration block.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# # bad, immediately causes Rails to load `app/graphql/types/thing.rb`
|
|
12
|
+
# field :thing, Types::Thing
|
|
13
|
+
#
|
|
14
|
+
# # good, defers loading until the file is needed
|
|
15
|
+
# field :thing do
|
|
16
|
+
# type(Types::Thing)
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
class FieldTypeInBlock < BaseCop
|
|
20
|
+
MSG = "type configuration can be moved to a block to defer loading the type's file"
|
|
21
|
+
|
|
22
|
+
BUILT_IN_SCALAR_NAMES = ["Float", "Int", "Integer", "String", "ID", "Boolean"]
|
|
23
|
+
def_node_matcher :field_config_with_inline_type, <<-Pattern
|
|
24
|
+
(
|
|
25
|
+
send {nil? _} :field sym ${const array} ...
|
|
26
|
+
)
|
|
27
|
+
Pattern
|
|
28
|
+
|
|
29
|
+
def_node_matcher :field_config_with_inline_type_and_block, <<-Pattern
|
|
30
|
+
(
|
|
31
|
+
block
|
|
32
|
+
(send {nil? _} :field sym ${const array} ...) ...
|
|
33
|
+
(args)
|
|
34
|
+
_
|
|
35
|
+
|
|
36
|
+
)
|
|
37
|
+
Pattern
|
|
38
|
+
|
|
39
|
+
def on_block(node)
|
|
40
|
+
ignore_node(node)
|
|
41
|
+
field_config_with_inline_type_and_block(node) do |type_const|
|
|
42
|
+
type_const_str = get_type_argument_str(node, type_const)
|
|
43
|
+
if ignore_inline_type_str?(type_const_str)
|
|
44
|
+
# Do nothing ...
|
|
45
|
+
else
|
|
46
|
+
add_offense(type_const) do |corrector|
|
|
47
|
+
cleaned_node_source = delete_type_argument(node, type_const)
|
|
48
|
+
field_indent = determine_field_indent(node)
|
|
49
|
+
cleaned_node_source.sub!(/(\{|do)/, "\\1\n#{field_indent} type #{type_const_str}")
|
|
50
|
+
corrector.replace(node, cleaned_node_source)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def on_send(node)
|
|
57
|
+
return if part_of_ignored_node?(node)
|
|
58
|
+
field_config_with_inline_type(node) do |type_const|
|
|
59
|
+
type_const_str = get_type_argument_str(node, type_const)
|
|
60
|
+
if ignore_inline_type_str?(type_const_str)
|
|
61
|
+
# Do nothing -- not loading from another file
|
|
62
|
+
else
|
|
63
|
+
add_offense(type_const) do |corrector|
|
|
64
|
+
cleaned_node_source = delete_type_argument(node, type_const)
|
|
65
|
+
field_indent = determine_field_indent(node)
|
|
66
|
+
cleaned_node_source += " do\n#{field_indent} type #{type_const_str}\n#{field_indent}end"
|
|
67
|
+
corrector.replace(node, cleaned_node_source)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def ignore_inline_type_str?(type_str)
|
|
77
|
+
if BUILT_IN_SCALAR_NAMES.include?(type_str)
|
|
78
|
+
true
|
|
79
|
+
elsif (inner_type_str = type_str.sub(/\[([A-Za-z]+)(, null: (true|false))?\]/, '\1')) && BUILT_IN_SCALAR_NAMES.include?(inner_type_str)
|
|
80
|
+
true
|
|
81
|
+
else
|
|
82
|
+
false
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def get_type_argument_str(send_node, type_const)
|
|
87
|
+
first_pos = type_const.location.expression.begin_pos
|
|
88
|
+
end_pos = type_const.location.expression.end_pos
|
|
89
|
+
node_source = send_node.source_range.source
|
|
90
|
+
node_first_pos = send_node.location.expression.begin_pos
|
|
91
|
+
|
|
92
|
+
relative_first_pos = first_pos - node_first_pos
|
|
93
|
+
end_removal_pos = end_pos - node_first_pos
|
|
94
|
+
|
|
95
|
+
node_source[relative_first_pos...end_removal_pos]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def delete_type_argument(send_node, type_const)
|
|
99
|
+
first_pos = type_const.location.expression.begin_pos
|
|
100
|
+
end_pos = type_const.location.expression.end_pos
|
|
101
|
+
node_source = send_node.source_range.source
|
|
102
|
+
node_first_pos = send_node.location.expression.begin_pos
|
|
103
|
+
|
|
104
|
+
relative_first_pos = first_pos - node_first_pos
|
|
105
|
+
end_removal_pos = end_pos - node_first_pos
|
|
106
|
+
|
|
107
|
+
begin_removal_pos = relative_first_pos
|
|
108
|
+
while node_source[begin_removal_pos] != ","
|
|
109
|
+
begin_removal_pos -= 1
|
|
110
|
+
if begin_removal_pos < 1
|
|
111
|
+
raise "Invariant: somehow backtracked to beginning of node looking for a comma (node source: #{node_source.inspect})"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
node_source[0...begin_removal_pos] + node_source[end_removal_pos..-1]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def determine_field_indent(send_node)
|
|
119
|
+
type_defn_node = send_node
|
|
120
|
+
|
|
121
|
+
while (type_defn_node && !(type_defn_node.class_definition? || type_defn_node.module_definition?))
|
|
122
|
+
type_defn_node = type_defn_node.parent
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if type_defn_node.nil?
|
|
126
|
+
raise "Invariant: Something went wrong in GraphQL-Ruby, couldn't find surrounding class definition for field (#{send_node}).\n\nPlease report this error on GitHub."
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
type_defn_source = type_defn_node.source
|
|
130
|
+
indent_test_idx = send_node.location.expression.begin_pos - type_defn_node.source_range.begin_pos - 1
|
|
131
|
+
field_indent = "".dup
|
|
132
|
+
while type_defn_source[indent_test_idx] == " "
|
|
133
|
+
field_indent << " "
|
|
134
|
+
indent_test_idx -= 1
|
|
135
|
+
if indent_test_idx == 0
|
|
136
|
+
raise "Invariant: somehow backtracted to beginning of class when looking for field indent (source: #{node_source.inspect})"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
field_indent
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative "./base_cop"
|
|
3
|
+
|
|
4
|
+
module GraphQL
|
|
5
|
+
module Rubocop
|
|
6
|
+
module GraphQL
|
|
7
|
+
# Identify (and auto-correct) any root types in your schema file.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# # bad, immediately causes Rails to load `app/graphql/types/query.rb`
|
|
11
|
+
# query Types::Query
|
|
12
|
+
#
|
|
13
|
+
# # good, defers loading until the file is needed
|
|
14
|
+
# query { Types::Query }
|
|
15
|
+
#
|
|
16
|
+
class RootTypesInBlock < BaseCop
|
|
17
|
+
MSG = "type configuration can be moved to a block to defer loading the type's file"
|
|
18
|
+
|
|
19
|
+
def_node_matcher :root_type_config_without_block, <<-Pattern
|
|
20
|
+
(
|
|
21
|
+
send nil? {:query :mutation :subscription} const
|
|
22
|
+
)
|
|
23
|
+
Pattern
|
|
24
|
+
|
|
25
|
+
def on_send(node)
|
|
26
|
+
root_type_config_without_block(node) do
|
|
27
|
+
add_offense(node) do |corrector|
|
|
28
|
+
new_node_source = node.source_range.source
|
|
29
|
+
new_node_source.sub!(/(query|mutation|subscription)/, '\1 {')
|
|
30
|
+
new_node_source << " }"
|
|
31
|
+
corrector.replace(node, new_node_source)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/graphql/rubocop.rb
CHANGED
|
@@ -12,7 +12,7 @@ module GraphQL
|
|
|
12
12
|
@possible_types = {}
|
|
13
13
|
@types = {}
|
|
14
14
|
@union_memberships = {}
|
|
15
|
-
@references = Hash.new { |h, k| h[k] =
|
|
15
|
+
@references = Hash.new { |h, k| h[k] = Set.new }
|
|
16
16
|
@arguments_with_default_values = []
|
|
17
17
|
add_type_and_traverse(new_types)
|
|
18
18
|
end
|
|
@@ -20,7 +20,7 @@ module GraphQL
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
22
|
def references_to(thing, from:)
|
|
23
|
-
@references[thing]
|
|
23
|
+
@references[thing].add(from)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def get_type(name)
|
|
@@ -40,7 +40,7 @@ module GraphQL
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def add_directives_from(owner)
|
|
43
|
-
if (dir_instances = owner.directives).
|
|
43
|
+
if !(dir_instances = owner.directives).empty?
|
|
44
44
|
dirs = dir_instances.map(&:class)
|
|
45
45
|
@directives.merge(dirs)
|
|
46
46
|
add_type_and_traverse(dirs)
|
|
@@ -95,7 +95,7 @@ module GraphQL
|
|
|
95
95
|
# It's a union with possible_types
|
|
96
96
|
# Replace the item by class name
|
|
97
97
|
owner.assign_type_membership_object_type(type)
|
|
98
|
-
@possible_types[owner
|
|
98
|
+
@possible_types[owner] = owner.possible_types
|
|
99
99
|
elsif type.kind.interface? && (owner.kind.object? || owner.kind.interface?)
|
|
100
100
|
new_interfaces = []
|
|
101
101
|
owner.interfaces.each do |int_t|
|
|
@@ -110,7 +110,7 @@ module GraphQL
|
|
|
110
110
|
end
|
|
111
111
|
owner.implements(*new_interfaces)
|
|
112
112
|
new_interfaces.each do |int|
|
|
113
|
-
pt = @possible_types[int
|
|
113
|
+
pt = @possible_types[int] ||= []
|
|
114
114
|
if !pt.include?(owner) && owner.is_a?(Class)
|
|
115
115
|
pt << owner
|
|
116
116
|
end
|
|
@@ -126,6 +126,7 @@ module GraphQL
|
|
|
126
126
|
@types[type.graphql_name] = type
|
|
127
127
|
when GraphQL::Schema::Field, GraphQL::Schema::Argument
|
|
128
128
|
orig_type = owner.type
|
|
129
|
+
unwrapped_t = type
|
|
129
130
|
# Apply list/non-null wrapper as needed
|
|
130
131
|
if orig_type.respond_to?(:of_type)
|
|
131
132
|
transforms = []
|
|
@@ -142,6 +143,7 @@ module GraphQL
|
|
|
142
143
|
transforms.reverse_each { |t| type = type.public_send(t) }
|
|
143
144
|
end
|
|
144
145
|
owner.type = type
|
|
146
|
+
references_to(unwrapped_t, from: owner)
|
|
145
147
|
else
|
|
146
148
|
raise "Unexpected update: #{owner.inspect} #{type.inspect}"
|
|
147
149
|
end
|
|
@@ -164,7 +166,9 @@ module GraphQL
|
|
|
164
166
|
@directives << type
|
|
165
167
|
type.all_argument_definitions.each do |arg|
|
|
166
168
|
arg_type = arg.type.unwrap
|
|
167
|
-
|
|
169
|
+
if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
|
|
170
|
+
references_to(arg_type, from: arg)
|
|
171
|
+
end
|
|
168
172
|
path.push(arg.graphql_name)
|
|
169
173
|
add_type(arg_type, owner: arg, late_types: late_types, path: path)
|
|
170
174
|
path.pop
|
|
@@ -185,16 +189,21 @@ module GraphQL
|
|
|
185
189
|
add_directives_from(type)
|
|
186
190
|
if type.kind.fields?
|
|
187
191
|
type.all_field_definitions.each do |field|
|
|
192
|
+
field.ensure_loaded
|
|
188
193
|
name = field.graphql_name
|
|
189
194
|
field_type = field.type.unwrap
|
|
190
|
-
|
|
195
|
+
if !field_type.is_a?(GraphQL::Schema::LateBoundType)
|
|
196
|
+
references_to(field_type, from: field)
|
|
197
|
+
end
|
|
191
198
|
path.push(name)
|
|
192
199
|
add_type(field_type, owner: field, late_types: late_types, path: path)
|
|
193
200
|
add_directives_from(field)
|
|
194
201
|
field.all_argument_definitions.each do |arg|
|
|
195
202
|
add_directives_from(arg)
|
|
196
203
|
arg_type = arg.type.unwrap
|
|
197
|
-
|
|
204
|
+
if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
|
|
205
|
+
references_to(arg_type, from: arg)
|
|
206
|
+
end
|
|
198
207
|
path.push(arg.graphql_name)
|
|
199
208
|
add_type(arg_type, owner: arg, late_types: late_types, path: path)
|
|
200
209
|
path.pop
|
|
@@ -209,7 +218,9 @@ module GraphQL
|
|
|
209
218
|
type.all_argument_definitions.each do |arg|
|
|
210
219
|
add_directives_from(arg)
|
|
211
220
|
arg_type = arg.type.unwrap
|
|
212
|
-
|
|
221
|
+
if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
|
|
222
|
+
references_to(arg_type, from: arg)
|
|
223
|
+
end
|
|
213
224
|
path.push(arg.graphql_name)
|
|
214
225
|
add_type(arg_type, owner: arg, late_types: late_types, path: path)
|
|
215
226
|
path.pop
|
|
@@ -219,7 +230,7 @@ module GraphQL
|
|
|
219
230
|
end
|
|
220
231
|
end
|
|
221
232
|
if type.kind.union?
|
|
222
|
-
@possible_types[type
|
|
233
|
+
@possible_types[type] = type.all_possible_types
|
|
223
234
|
path.push("possible_types")
|
|
224
235
|
type.all_possible_types.each do |t|
|
|
225
236
|
add_type(t, owner: type, late_types: late_types, path: path)
|
|
@@ -234,7 +245,7 @@ module GraphQL
|
|
|
234
245
|
path.pop
|
|
235
246
|
end
|
|
236
247
|
if type.kind.object?
|
|
237
|
-
possible_types_for_this_name = @possible_types[type
|
|
248
|
+
possible_types_for_this_name = @possible_types[type] ||= []
|
|
238
249
|
possible_types_for_this_name << type
|
|
239
250
|
end
|
|
240
251
|
|
|
@@ -246,8 +257,10 @@ module GraphQL
|
|
|
246
257
|
interface_type = interface_type_membership.abstract_type
|
|
247
258
|
# We can get these now; we'll have to get late-bound types later
|
|
248
259
|
if interface_type.is_a?(Module) && type.is_a?(Class)
|
|
249
|
-
implementers = @possible_types[interface_type
|
|
250
|
-
implementers
|
|
260
|
+
implementers = @possible_types[interface_type] ||= []
|
|
261
|
+
if !implementers.include?(type)
|
|
262
|
+
implementers << type
|
|
263
|
+
end
|
|
251
264
|
end
|
|
252
265
|
when String, Schema::LateBoundType
|
|
253
266
|
interface_type = interface_type_membership
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module GraphQL
|
|
3
3
|
class Schema
|
|
4
|
-
|
|
4
|
+
module AlwaysVisible
|
|
5
5
|
def self.use(schema, **opts)
|
|
6
|
-
schema.
|
|
6
|
+
schema.use(GraphQL::Schema::Visibility, profiles: { nil => {} })
|
|
7
|
+
schema.extend(self)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def visible?(_member, _context)
|
|
11
|
+
true
|
|
7
12
|
end
|
|
8
13
|
end
|
|
9
14
|
end
|
|
@@ -4,6 +4,7 @@ module GraphQL
|
|
|
4
4
|
class Argument
|
|
5
5
|
include GraphQL::Schema::Member::HasPath
|
|
6
6
|
include GraphQL::Schema::Member::HasAstNode
|
|
7
|
+
include GraphQL::Schema::Member::HasAuthorization
|
|
7
8
|
include GraphQL::Schema::Member::HasDirectives
|
|
8
9
|
include GraphQL::Schema::Member::HasDeprecationReason
|
|
9
10
|
include GraphQL::Schema::Member::HasValidators
|
|
@@ -39,9 +40,14 @@ module GraphQL
|
|
|
39
40
|
# @param arg_name [Symbol]
|
|
40
41
|
# @param type_expr
|
|
41
42
|
# @param desc [String]
|
|
43
|
+
# @param type [Class, Array<Class>] Input type; positional argument also accepted
|
|
44
|
+
# @param name [Symbol] positional argument also accepted # @param loads [Class, Array<Class>] A GraphQL type to load for the given ID when one is present
|
|
45
|
+
# @param definition_block [Proc] Called with the newly-created {Argument}
|
|
46
|
+
# @param owner [Class] Private, used by GraphQL-Ruby during schema definition
|
|
42
47
|
# @param required [Boolean, :nullable] if true, this argument is non-null; if false, this argument is nullable. If `:nullable`, then the argument must be provided, though it may be `null`.
|
|
43
48
|
# @param description [String]
|
|
44
49
|
# @param default_value [Object]
|
|
50
|
+
# @param loads [Class, Array<Class>] A GraphQL type to load for the given ID when one is present
|
|
45
51
|
# @param as [Symbol] Override the keyword name when passed to a method
|
|
46
52
|
# @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
|
|
47
53
|
# @param camelize [Boolean] if true, the name will be camelized when building the schema
|
|
@@ -50,11 +56,15 @@ module GraphQL
|
|
|
50
56
|
# @param deprecation_reason [String]
|
|
51
57
|
# @param validates [Hash, nil] Options for building validators, if any should be applied
|
|
52
58
|
# @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
|
|
53
|
-
|
|
59
|
+
# @param comment [String] Private, used by GraphQL-Ruby when parsing GraphQL schema files
|
|
60
|
+
# @param ast_node [GraphQL::Language::Nodes::InputValueDefinition] Private, used by GraphQL-Ruby when parsing schema files
|
|
61
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, comment: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
|
54
62
|
arg_name ||= name
|
|
55
63
|
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
|
64
|
+
NameValidator.validate!(@name)
|
|
56
65
|
@type_expr = type_expr || type
|
|
57
66
|
@description = desc || description
|
|
67
|
+
@comment = comment
|
|
58
68
|
@null = required != true
|
|
59
69
|
@default_value = default_value
|
|
60
70
|
if replace_null_with_default
|
|
@@ -88,11 +98,8 @@ module GraphQL
|
|
|
88
98
|
end
|
|
89
99
|
|
|
90
100
|
if definition_block
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
else
|
|
94
|
-
instance_eval(&definition_block)
|
|
95
|
-
end
|
|
101
|
+
# `self` will still be self, it will also be the first argument to the block:
|
|
102
|
+
instance_exec(self, &definition_block)
|
|
96
103
|
end
|
|
97
104
|
end
|
|
98
105
|
|
|
@@ -129,6 +136,17 @@ module GraphQL
|
|
|
129
136
|
end
|
|
130
137
|
end
|
|
131
138
|
|
|
139
|
+
attr_writer :comment
|
|
140
|
+
|
|
141
|
+
# @return [String] Comment for this argument
|
|
142
|
+
def comment(text = nil)
|
|
143
|
+
if text
|
|
144
|
+
@comment = text
|
|
145
|
+
else
|
|
146
|
+
@comment
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
132
150
|
# @return [String] Deprecation reason for this argument
|
|
133
151
|
def deprecation_reason(text = nil)
|
|
134
152
|
if text
|
|
@@ -147,6 +165,10 @@ module GraphQL
|
|
|
147
165
|
true
|
|
148
166
|
end
|
|
149
167
|
|
|
168
|
+
def authorizes?(_context)
|
|
169
|
+
self.method(:authorized?).owner != GraphQL::Schema::Argument
|
|
170
|
+
end
|
|
171
|
+
|
|
150
172
|
def authorized?(obj, value, ctx)
|
|
151
173
|
authorized_as_type?(obj, value, ctx, as_type: type)
|
|
152
174
|
end
|
|
@@ -202,12 +224,17 @@ module GraphQL
|
|
|
202
224
|
@statically_coercible = !requires_parent_object
|
|
203
225
|
end
|
|
204
226
|
|
|
227
|
+
def freeze
|
|
228
|
+
statically_coercible?
|
|
229
|
+
super
|
|
230
|
+
end
|
|
231
|
+
|
|
205
232
|
# Apply the {prepare} configuration to `value`, using methods from `obj`.
|
|
206
233
|
# Used by the runtime.
|
|
207
234
|
# @api private
|
|
208
235
|
def prepare_value(obj, value, context: nil)
|
|
209
|
-
if
|
|
210
|
-
value = value
|
|
236
|
+
if type.unwrap.kind.input_object?
|
|
237
|
+
value = recursively_prepare_input_object(value, type, context)
|
|
211
238
|
end
|
|
212
239
|
|
|
213
240
|
Schema::Validator.validate!(validators, obj, context, value)
|
|
@@ -221,8 +248,13 @@ module GraphQL
|
|
|
221
248
|
#
|
|
222
249
|
# This will have to be called later, when the runtime object _is_ available.
|
|
223
250
|
value
|
|
224
|
-
|
|
251
|
+
elsif obj.respond_to?(@prepare)
|
|
225
252
|
obj.public_send(@prepare, value)
|
|
253
|
+
elsif owner.respond_to?(@prepare)
|
|
254
|
+
owner.public_send(@prepare, value, context || obj.context)
|
|
255
|
+
else
|
|
256
|
+
raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}. "\
|
|
257
|
+
"Could not find prepare method #{@prepare} on #{obj.class} or #{owner}."
|
|
226
258
|
end
|
|
227
259
|
elsif @prepare.respond_to?(:call)
|
|
228
260
|
@prepare.call(value, context || obj.context)
|
|
@@ -285,6 +317,7 @@ module GraphQL
|
|
|
285
317
|
# TODO code smell to access such a deeply-nested constant in a distant module
|
|
286
318
|
argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
|
|
287
319
|
value: resolved_loaded_value,
|
|
320
|
+
original_value: resolved_coerced_value,
|
|
288
321
|
definition: self,
|
|
289
322
|
default_used: default_used,
|
|
290
323
|
)
|
|
@@ -306,10 +339,15 @@ module GraphQL
|
|
|
306
339
|
context.query.after_lazy(custom_loaded_value) do |custom_value|
|
|
307
340
|
if loads
|
|
308
341
|
if type.list?
|
|
309
|
-
loaded_values =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
342
|
+
loaded_values = []
|
|
343
|
+
context.dataloader.run_isolated do
|
|
344
|
+
custom_value.each_with_index.map { |custom_val, idx|
|
|
345
|
+
id = coerced_value[idx]
|
|
346
|
+
context.dataloader.append_job do
|
|
347
|
+
loaded_values[idx] = load_method_owner.authorize_application_object(self, id, context, custom_val)
|
|
348
|
+
end
|
|
349
|
+
}
|
|
350
|
+
end
|
|
313
351
|
context.schema.after_any_lazies(loaded_values, &:itself)
|
|
314
352
|
else
|
|
315
353
|
load_method_owner.authorize_application_object(self, coerced_value, context, custom_loaded_value)
|
|
@@ -320,7 +358,16 @@ module GraphQL
|
|
|
320
358
|
end
|
|
321
359
|
elsif loads
|
|
322
360
|
if type.list?
|
|
323
|
-
loaded_values =
|
|
361
|
+
loaded_values = []
|
|
362
|
+
# We want to run these list items all together,
|
|
363
|
+
# but we also need to wait for the result so we can return it :S
|
|
364
|
+
context.dataloader.run_isolated do
|
|
365
|
+
coerced_value.each_with_index { |val, idx|
|
|
366
|
+
context.dataloader.append_job do
|
|
367
|
+
loaded_values[idx] = load_method_owner.load_and_authorize_application_object(self, val, context)
|
|
368
|
+
end
|
|
369
|
+
}
|
|
370
|
+
end
|
|
324
371
|
context.schema.after_any_lazies(loaded_values, &:itself)
|
|
325
372
|
else
|
|
326
373
|
load_method_owner.load_and_authorize_application_object(self, coerced_value, context)
|
|
@@ -332,6 +379,7 @@ module GraphQL
|
|
|
332
379
|
|
|
333
380
|
# @api private
|
|
334
381
|
def validate_default_value
|
|
382
|
+
return unless default_value?
|
|
335
383
|
coerced_default_value = begin
|
|
336
384
|
# This is weird, but we should accept single-item default values for list-type arguments.
|
|
337
385
|
# If we used `coerce_isolated_input` below, it would do this for us, but it's not really
|
|
@@ -367,6 +415,22 @@ module GraphQL
|
|
|
367
415
|
|
|
368
416
|
private
|
|
369
417
|
|
|
418
|
+
def recursively_prepare_input_object(value, type, context)
|
|
419
|
+
if type.non_null?
|
|
420
|
+
type = type.of_type
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
if type.list? && !value.nil?
|
|
424
|
+
inner_type = type.of_type
|
|
425
|
+
value.map { |v| recursively_prepare_input_object(v, inner_type, context) }
|
|
426
|
+
elsif value.is_a?(GraphQL::Schema::InputObject)
|
|
427
|
+
value.validate_for(context)
|
|
428
|
+
value.prepare
|
|
429
|
+
else
|
|
430
|
+
value
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
|
|
370
434
|
def validate_input_type(input_type)
|
|
371
435
|
if input_type.is_a?(String) || input_type.is_a?(GraphQL::Schema::LateBoundType)
|
|
372
436
|
# Do nothing; assume this will be validated later
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'graphql/schema/base_64_bp'
|
|
4
|
-
|
|
2
|
+
require "base64"
|
|
5
3
|
module GraphQL
|
|
6
4
|
class Schema
|
|
7
5
|
# @api private
|
|
8
6
|
module Base64Encoder
|
|
9
7
|
def self.encode(unencoded_text, nonce: false)
|
|
10
|
-
|
|
8
|
+
Base64.urlsafe_encode64(unencoded_text, padding: false)
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
def self.decode(encoded_text, nonce: false)
|
|
14
12
|
# urlsafe_decode64 is for forward compatibility
|
|
15
|
-
|
|
13
|
+
Base64.urlsafe_decode64(encoded_text)
|
|
16
14
|
rescue ArgumentError
|
|
17
15
|
raise GraphQL::ExecutionError, "Invalid input: #{encoded_text.inspect}"
|
|
18
16
|
end
|