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
|
@@ -7,15 +7,21 @@ module GraphQL
|
|
|
7
7
|
class << self
|
|
8
8
|
# @see {Schema.from_definition}
|
|
9
9
|
def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser, **kwargs)
|
|
10
|
+
if defined?(parser::SchemaParser)
|
|
11
|
+
parser = parser::SchemaParser
|
|
12
|
+
end
|
|
10
13
|
from_document(schema_superclass, parser.parse(definition_string), **kwargs)
|
|
11
14
|
end
|
|
12
15
|
|
|
13
16
|
def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser, **kwargs)
|
|
17
|
+
if defined?(parser::SchemaParser)
|
|
18
|
+
parser = parser::SchemaParser
|
|
19
|
+
end
|
|
14
20
|
from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
|
|
15
21
|
end
|
|
16
22
|
|
|
17
|
-
def from_document(schema_superclass, document, default_resolve:, using: {}, relay: false)
|
|
18
|
-
Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using)
|
|
23
|
+
def from_document(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay: false)
|
|
24
|
+
Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using, base_types: base_types)
|
|
19
25
|
end
|
|
20
26
|
end
|
|
21
27
|
|
|
@@ -24,9 +30,18 @@ module GraphQL
|
|
|
24
30
|
include GraphQL::EmptyObjects
|
|
25
31
|
extend self
|
|
26
32
|
|
|
27
|
-
def build(schema_superclass, document, default_resolve:, using: {}, relay:)
|
|
33
|
+
def build(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay:)
|
|
28
34
|
raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
|
|
29
35
|
|
|
36
|
+
base_types = {
|
|
37
|
+
object: GraphQL::Schema::Object,
|
|
38
|
+
interface: GraphQL::Schema::Interface,
|
|
39
|
+
union: GraphQL::Schema::Union,
|
|
40
|
+
scalar: GraphQL::Schema::Scalar,
|
|
41
|
+
enum: GraphQL::Schema::Enum,
|
|
42
|
+
input_object: GraphQL::Schema::InputObject,
|
|
43
|
+
}.merge!(base_types)
|
|
44
|
+
|
|
30
45
|
if default_resolve.is_a?(Hash)
|
|
31
46
|
default_resolve = ResolveMap.new(default_resolve)
|
|
32
47
|
end
|
|
@@ -47,7 +62,7 @@ module GraphQL
|
|
|
47
62
|
types[type_name] ||= begin
|
|
48
63
|
defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
|
|
49
64
|
if defn
|
|
50
|
-
build_definition_from_node(defn, directive_type_resolver, default_resolve)
|
|
65
|
+
build_definition_from_node(defn, directive_type_resolver, default_resolve, base_types)
|
|
51
66
|
elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
|
|
52
67
|
built_in_defn
|
|
53
68
|
else
|
|
@@ -71,14 +86,30 @@ module GraphQL
|
|
|
71
86
|
case definition
|
|
72
87
|
when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
|
|
73
88
|
nil # already handled
|
|
74
|
-
when GraphQL::Language::Nodes::SchemaExtension
|
|
89
|
+
when GraphQL::Language::Nodes::SchemaExtension,
|
|
90
|
+
GraphQL::Language::Nodes::ScalarTypeExtension,
|
|
91
|
+
GraphQL::Language::Nodes::ObjectTypeExtension,
|
|
92
|
+
GraphQL::Language::Nodes::InterfaceTypeExtension,
|
|
93
|
+
GraphQL::Language::Nodes::UnionTypeExtension,
|
|
94
|
+
GraphQL::Language::Nodes::EnumTypeExtension,
|
|
95
|
+
GraphQL::Language::Nodes::InputObjectTypeExtension
|
|
75
96
|
schema_extensions ||= []
|
|
76
97
|
schema_extensions << definition
|
|
77
98
|
else
|
|
78
99
|
# It's possible that this was already loaded by the directives
|
|
79
100
|
prev_type = types[definition.name]
|
|
80
101
|
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
|
|
81
|
-
|
|
102
|
+
if definition.is_a?(GraphQL::Language::Nodes::ObjectTypeDefinition) || definition.is_a?(Language::Nodes::InterfaceTypeDefinition)
|
|
103
|
+
interface_names = definition.interfaces.map(&:name)
|
|
104
|
+
transitive_names = interface_names.map { |n| document.definitions.find { |d| d.respond_to?(:name) && d.name == n }&.interfaces&.map(&:name) }
|
|
105
|
+
transitive_names.flatten!
|
|
106
|
+
transitive_names.compact!
|
|
107
|
+
if !(missing_transitive_interfaces = transitive_names - interface_names).empty?
|
|
108
|
+
raise GraphQL::Schema::InvalidDocumentError, "type #{definition.name} is missing one or more transitive interface names: #{missing_transitive_interfaces.join(", ")}. Add them to the type's `implements` list and try again."
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve, base_types)
|
|
82
113
|
end
|
|
83
114
|
end
|
|
84
115
|
end
|
|
@@ -118,12 +149,43 @@ module GraphQL
|
|
|
118
149
|
|
|
119
150
|
raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
|
|
120
151
|
|
|
152
|
+
schema_extensions&.each do |ext|
|
|
153
|
+
next if ext.is_a?(GraphQL::Language::Nodes::SchemaExtension)
|
|
154
|
+
|
|
155
|
+
built_type = types[ext.name]
|
|
156
|
+
|
|
157
|
+
case ext
|
|
158
|
+
when GraphQL::Language::Nodes::ScalarTypeExtension
|
|
159
|
+
build_directives(built_type, ext, type_resolver)
|
|
160
|
+
when GraphQL::Language::Nodes::ObjectTypeExtension
|
|
161
|
+
build_directives(built_type, ext, type_resolver)
|
|
162
|
+
build_fields(built_type, ext.fields, type_resolver, default_resolve: true)
|
|
163
|
+
build_interfaces(built_type, ext.interfaces, type_resolver)
|
|
164
|
+
when GraphQL::Language::Nodes::InterfaceTypeExtension
|
|
165
|
+
build_directives(built_type, ext, type_resolver)
|
|
166
|
+
build_fields(built_type, ext.fields, type_resolver, default_resolve: nil)
|
|
167
|
+
build_interfaces(built_type, ext.interfaces, type_resolver)
|
|
168
|
+
when GraphQL::Language::Nodes::UnionTypeExtension
|
|
169
|
+
build_directives(built_type, ext, type_resolver)
|
|
170
|
+
built_type.possible_types(*ext.types.map { |type_name| type_resolver.call(type_name) })
|
|
171
|
+
when GraphQL::Language::Nodes::EnumTypeExtension
|
|
172
|
+
build_directives(built_type, ext, type_resolver)
|
|
173
|
+
build_values(built_type, ext.values, type_resolver)
|
|
174
|
+
when GraphQL::Language::Nodes::InputObjectTypeExtension
|
|
175
|
+
build_directives(built_type, ext, type_resolver)
|
|
176
|
+
build_arguments(built_type, ext.fields, type_resolver)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
121
180
|
builder = self
|
|
122
181
|
|
|
182
|
+
found_types = types.values
|
|
183
|
+
object_types = found_types.select { |t| t.respond_to?(:kind) && t.kind.object? }
|
|
123
184
|
schema_class = Class.new(schema_superclass) do
|
|
124
185
|
begin
|
|
125
186
|
# Add these first so that there's some chance of resolving late-bound types
|
|
126
|
-
|
|
187
|
+
add_type_and_traverse(found_types, root: false)
|
|
188
|
+
orphan_types(object_types)
|
|
127
189
|
query query_root_type
|
|
128
190
|
mutation mutation_root_type
|
|
129
191
|
subscription subscription_root_type
|
|
@@ -133,6 +195,16 @@ module GraphQL
|
|
|
133
195
|
raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
|
|
134
196
|
end
|
|
135
197
|
|
|
198
|
+
object_types.each do |t|
|
|
199
|
+
t.interfaces.each do |int_t|
|
|
200
|
+
if int_t.is_a?(LateBoundType)
|
|
201
|
+
int_t = types[int_t.graphql_name]
|
|
202
|
+
t.implements(int_t)
|
|
203
|
+
end
|
|
204
|
+
int_t.orphan_types(t)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
136
208
|
if default_resolve.respond_to?(:resolve_type)
|
|
137
209
|
def self.resolve_type(*args)
|
|
138
210
|
self.definition_default_resolve.resolve_type(*args)
|
|
@@ -173,11 +245,12 @@ module GraphQL
|
|
|
173
245
|
|
|
174
246
|
def self.inherited(child_class)
|
|
175
247
|
child_class.definition_default_resolve = self.definition_default_resolve
|
|
248
|
+
super
|
|
176
249
|
end
|
|
177
250
|
end
|
|
178
251
|
|
|
179
|
-
|
|
180
|
-
|
|
252
|
+
schema_extensions&.each do |ext|
|
|
253
|
+
if ext.is_a?(GraphQL::Language::Nodes::SchemaExtension)
|
|
181
254
|
build_directives(schema_class, ext, type_resolver)
|
|
182
255
|
end
|
|
183
256
|
end
|
|
@@ -189,20 +262,22 @@ module GraphQL
|
|
|
189
262
|
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
|
|
190
263
|
}
|
|
191
264
|
|
|
192
|
-
def build_definition_from_node(definition, type_resolver, default_resolve)
|
|
265
|
+
def build_definition_from_node(definition, type_resolver, default_resolve, base_types)
|
|
193
266
|
case definition
|
|
194
267
|
when GraphQL::Language::Nodes::EnumTypeDefinition
|
|
195
|
-
build_enum_type(definition, type_resolver)
|
|
268
|
+
build_enum_type(definition, type_resolver, base_types[:enum])
|
|
196
269
|
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
|
197
|
-
build_object_type(definition, type_resolver)
|
|
270
|
+
build_object_type(definition, type_resolver, base_types[:object])
|
|
198
271
|
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
|
199
|
-
build_interface_type(definition, type_resolver)
|
|
272
|
+
build_interface_type(definition, type_resolver, base_types[:interface])
|
|
200
273
|
when GraphQL::Language::Nodes::UnionTypeDefinition
|
|
201
|
-
build_union_type(definition, type_resolver)
|
|
274
|
+
build_union_type(definition, type_resolver, base_types[:union])
|
|
202
275
|
when GraphQL::Language::Nodes::ScalarTypeDefinition
|
|
203
|
-
build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
|
|
276
|
+
build_scalar_type(definition, type_resolver, base_types[:scalar], default_resolve: default_resolve)
|
|
204
277
|
when GraphQL::Language::Nodes::InputObjectTypeDefinition
|
|
205
|
-
build_input_object_type(definition, type_resolver)
|
|
278
|
+
build_input_object_type(definition, type_resolver, base_types[:input_object])
|
|
279
|
+
when GraphQL::Language::Nodes::DirectiveDefinition
|
|
280
|
+
build_directive(definition, type_resolver)
|
|
206
281
|
end
|
|
207
282
|
end
|
|
208
283
|
|
|
@@ -268,22 +343,26 @@ module GraphQL
|
|
|
268
343
|
end
|
|
269
344
|
end
|
|
270
345
|
|
|
271
|
-
def build_enum_type(enum_type_definition, type_resolver)
|
|
346
|
+
def build_enum_type(enum_type_definition, type_resolver, base_type)
|
|
272
347
|
builder = self
|
|
273
|
-
Class.new(
|
|
348
|
+
Class.new(base_type) do
|
|
274
349
|
graphql_name(enum_type_definition.name)
|
|
275
350
|
builder.build_directives(self, enum_type_definition, type_resolver)
|
|
276
351
|
description(enum_type_definition.description)
|
|
277
352
|
ast_node(enum_type_definition)
|
|
278
|
-
enum_type_definition.values
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
353
|
+
builder.build_values(self, enum_type_definition.values, type_resolver)
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def build_values(type_class, enum_value_definitions, type_resolver)
|
|
358
|
+
enum_value_definitions.each do |enum_value_definition|
|
|
359
|
+
type_class.value(enum_value_definition.name,
|
|
360
|
+
value: enum_value_definition.name,
|
|
361
|
+
deprecation_reason: build_deprecation_reason(enum_value_definition.directives),
|
|
362
|
+
description: enum_value_definition.description,
|
|
363
|
+
directives: prepare_directives(enum_value_definition, type_resolver),
|
|
364
|
+
ast_node: enum_value_definition,
|
|
365
|
+
)
|
|
287
366
|
end
|
|
288
367
|
end
|
|
289
368
|
|
|
@@ -297,9 +376,9 @@ module GraphQL
|
|
|
297
376
|
reason.value
|
|
298
377
|
end
|
|
299
378
|
|
|
300
|
-
def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
|
|
379
|
+
def build_scalar_type(scalar_type_definition, type_resolver, base_type, default_resolve:)
|
|
301
380
|
builder = self
|
|
302
|
-
Class.new(
|
|
381
|
+
Class.new(base_type) do
|
|
303
382
|
graphql_name(scalar_type_definition.name)
|
|
304
383
|
description(scalar_type_definition.description)
|
|
305
384
|
ast_node(scalar_type_definition)
|
|
@@ -320,9 +399,9 @@ module GraphQL
|
|
|
320
399
|
end
|
|
321
400
|
end
|
|
322
401
|
|
|
323
|
-
def build_union_type(union_type_definition, type_resolver)
|
|
402
|
+
def build_union_type(union_type_definition, type_resolver, base_type)
|
|
324
403
|
builder = self
|
|
325
|
-
Class.new(
|
|
404
|
+
Class.new(base_type) do
|
|
326
405
|
graphql_name(union_type_definition.name)
|
|
327
406
|
description(union_type_definition.description)
|
|
328
407
|
possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
|
|
@@ -331,27 +410,28 @@ module GraphQL
|
|
|
331
410
|
end
|
|
332
411
|
end
|
|
333
412
|
|
|
334
|
-
def build_object_type(object_type_definition, type_resolver)
|
|
413
|
+
def build_object_type(object_type_definition, type_resolver, base_type)
|
|
335
414
|
builder = self
|
|
336
415
|
|
|
337
|
-
Class.new(
|
|
416
|
+
Class.new(base_type) do
|
|
338
417
|
graphql_name(object_type_definition.name)
|
|
339
418
|
description(object_type_definition.description)
|
|
340
419
|
ast_node(object_type_definition)
|
|
341
420
|
builder.build_directives(self, object_type_definition, type_resolver)
|
|
342
|
-
|
|
343
|
-
object_type_definition.interfaces.each do |interface_name|
|
|
344
|
-
interface_defn = type_resolver.call(interface_name)
|
|
345
|
-
implements(interface_defn)
|
|
346
|
-
end
|
|
347
|
-
|
|
421
|
+
builder.build_interfaces(self, object_type_definition.interfaces, type_resolver)
|
|
348
422
|
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
|
349
423
|
end
|
|
350
424
|
end
|
|
351
425
|
|
|
352
|
-
def
|
|
426
|
+
def build_interfaces(type_class, interface_names, type_resolver)
|
|
427
|
+
interface_names.each do |interface_name|
|
|
428
|
+
type_class.implements(type_resolver.call(interface_name))
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def build_input_object_type(input_object_type_definition, type_resolver, base_type)
|
|
353
433
|
builder = self
|
|
354
|
-
Class.new(
|
|
434
|
+
Class.new(base_type) do
|
|
355
435
|
graphql_name(input_object_type_definition.name)
|
|
356
436
|
description(input_object_type_definition.description)
|
|
357
437
|
ast_node(input_object_type_definition)
|
|
@@ -411,16 +491,13 @@ module GraphQL
|
|
|
411
491
|
end
|
|
412
492
|
end
|
|
413
493
|
|
|
414
|
-
def build_interface_type(interface_type_definition, type_resolver)
|
|
494
|
+
def build_interface_type(interface_type_definition, type_resolver, base_type)
|
|
415
495
|
builder = self
|
|
416
496
|
Module.new do
|
|
417
|
-
include
|
|
497
|
+
include base_type
|
|
418
498
|
graphql_name(interface_type_definition.name)
|
|
419
499
|
description(interface_type_definition.description)
|
|
420
|
-
interface_type_definition.interfaces
|
|
421
|
-
interface_defn = type_resolver.call(interface_name)
|
|
422
|
-
implements(interface_defn)
|
|
423
|
-
end
|
|
500
|
+
builder.build_interfaces(self, interface_type_definition.interfaces, type_resolver)
|
|
424
501
|
ast_node(interface_type_definition)
|
|
425
502
|
builder.build_directives(self, interface_type_definition, type_resolver)
|
|
426
503
|
|
|
@@ -432,14 +509,12 @@ module GraphQL
|
|
|
432
509
|
builder = self
|
|
433
510
|
|
|
434
511
|
field_definitions.each do |field_definition|
|
|
435
|
-
type_name = resolve_type_name(field_definition.type)
|
|
436
512
|
resolve_method_name = -"resolve_field_#{field_definition.name}"
|
|
437
513
|
schema_field_defn = owner.field(
|
|
438
514
|
field_definition.name,
|
|
439
515
|
description: field_definition.description,
|
|
440
516
|
type: type_resolver.call(field_definition.type),
|
|
441
517
|
null: true,
|
|
442
|
-
connection: type_name.end_with?("Connection"),
|
|
443
518
|
connection_extension: nil,
|
|
444
519
|
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
|
445
520
|
ast_node: field_definition,
|
|
@@ -447,23 +522,31 @@ module GraphQL
|
|
|
447
522
|
camelize: false,
|
|
448
523
|
directives: prepare_directives(field_definition, type_resolver),
|
|
449
524
|
resolver_method: resolve_method_name,
|
|
525
|
+
resolve_batch: resolve_method_name,
|
|
450
526
|
)
|
|
451
527
|
|
|
452
528
|
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
|
453
529
|
|
|
454
530
|
# Don't do this for interfaces
|
|
455
531
|
if default_resolve
|
|
456
|
-
owner
|
|
457
|
-
# frozen_string_literal: true
|
|
458
|
-
def #{resolve_method_name}(**args)
|
|
459
|
-
field_instance = self.class.get_field("#{field_definition.name}")
|
|
460
|
-
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
|
461
|
-
end
|
|
462
|
-
RUBY
|
|
532
|
+
define_field_resolve_method(owner, resolve_method_name, field_definition.name)
|
|
463
533
|
end
|
|
464
534
|
end
|
|
465
535
|
end
|
|
466
536
|
|
|
537
|
+
def define_field_resolve_method(owner, method_name, field_name)
|
|
538
|
+
owner.define_method(method_name) { |**args|
|
|
539
|
+
field_instance = context.types.field(owner, field_name)
|
|
540
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
|
541
|
+
}
|
|
542
|
+
owner.define_singleton_method(method_name) { |objects, context, **args|
|
|
543
|
+
field_instance = context.types.field(owner, field_name)
|
|
544
|
+
objects.map do |object|
|
|
545
|
+
context.schema.definition_default_resolve.call(self, field_instance, object, args, context)
|
|
546
|
+
end
|
|
547
|
+
}
|
|
548
|
+
end
|
|
549
|
+
|
|
467
550
|
def build_resolve_type(lookup_hash, directives, missing_type_handler)
|
|
468
551
|
resolve_type_proc = nil
|
|
469
552
|
resolve_type_proc = ->(ast_node) {
|
|
@@ -480,22 +563,13 @@ module GraphQL
|
|
|
480
563
|
when GraphQL::Language::Nodes::ListType
|
|
481
564
|
resolve_type_proc.call(ast_node.of_type).to_list_type
|
|
482
565
|
when String
|
|
483
|
-
directives[ast_node]
|
|
566
|
+
directives[ast_node] ||= missing_type_handler.call(ast_node)
|
|
484
567
|
else
|
|
485
568
|
raise "Unexpected ast_node: #{ast_node.inspect}"
|
|
486
569
|
end
|
|
487
570
|
}
|
|
488
571
|
resolve_type_proc
|
|
489
572
|
end
|
|
490
|
-
|
|
491
|
-
def resolve_type_name(type)
|
|
492
|
-
case type
|
|
493
|
-
when GraphQL::Language::Nodes::TypeName
|
|
494
|
-
return type.name
|
|
495
|
-
else
|
|
496
|
-
resolve_type_name(type.of_type)
|
|
497
|
-
end
|
|
498
|
-
end
|
|
499
573
|
end
|
|
500
574
|
|
|
501
575
|
private_constant :Builder
|
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
|
7
7
|
# In this case, the server hides types and fields _entirely_, unless the current context has certain `:flags` present.
|
|
8
8
|
class Flagged < GraphQL::Schema::Directive
|
|
9
9
|
def initialize(target, **options)
|
|
10
|
-
if target.is_a?(Module)
|
|
10
|
+
if target.is_a?(Module)
|
|
11
11
|
# This is type class of some kind, `include` will put this module
|
|
12
12
|
# in between the type class itself and its super class, so `super` will work fine
|
|
13
13
|
target.include(VisibleByFlag)
|
|
@@ -37,6 +37,8 @@ module GraphQL
|
|
|
37
37
|
|
|
38
38
|
argument :by, [String], "Flags to check for this schema member"
|
|
39
39
|
|
|
40
|
+
repeatable(true)
|
|
41
|
+
|
|
40
42
|
module VisibleByFlag
|
|
41
43
|
def self.included(schema_class)
|
|
42
44
|
schema_class.extend(self)
|
|
@@ -45,7 +47,7 @@ module GraphQL
|
|
|
45
47
|
def visible?(context)
|
|
46
48
|
if dir = self.directives.find { |d| d.is_a?(Flagged) }
|
|
47
49
|
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
|
48
|
-
relevant_flags && relevant_flags.
|
|
50
|
+
relevant_flags && !relevant_flags.empty? && super
|
|
49
51
|
else
|
|
50
52
|
super
|
|
51
53
|
end
|
|
@@ -6,6 +6,18 @@ module GraphQL
|
|
|
6
6
|
description "Requires that exactly one field must be supplied and that field must not be `null`."
|
|
7
7
|
locations(GraphQL::Schema::Directive::INPUT_OBJECT)
|
|
8
8
|
default_directive true
|
|
9
|
+
|
|
10
|
+
def initialize(...)
|
|
11
|
+
super
|
|
12
|
+
|
|
13
|
+
owner.extend(IsOneOf)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module IsOneOf
|
|
17
|
+
def one_of?
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
9
21
|
end
|
|
10
22
|
end
|
|
11
23
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module GraphQL
|
|
3
|
+
class Schema
|
|
4
|
+
class Directive < GraphQL::Schema::Member
|
|
5
|
+
class SpecifiedBy < GraphQL::Schema::Directive
|
|
6
|
+
description "Exposes a URL that specifies the behavior of this scalar."
|
|
7
|
+
locations(GraphQL::Schema::Directive::SCALAR)
|
|
8
|
+
default_directive true
|
|
9
|
+
|
|
10
|
+
argument :url, String, description: "The URL that specifies the behavior of this scalar."
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -9,6 +9,7 @@ module GraphQL
|
|
|
9
9
|
class Directive < GraphQL::Schema::Member
|
|
10
10
|
extend GraphQL::Schema::Member::HasArguments
|
|
11
11
|
extend GraphQL::Schema::Member::HasArguments::HasDirectiveArguments
|
|
12
|
+
extend GraphQL::Schema::Member::HasValidators
|
|
12
13
|
|
|
13
14
|
class << self
|
|
14
15
|
# Directives aren't types, they don't have kinds.
|
|
@@ -29,18 +30,26 @@ module GraphQL
|
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def locations(*new_locations)
|
|
32
|
-
if new_locations.
|
|
33
|
+
if !new_locations.empty?
|
|
34
|
+
is_runtime = false
|
|
33
35
|
new_locations.each do |new_loc|
|
|
34
|
-
|
|
36
|
+
loc_sym = new_loc.to_sym
|
|
37
|
+
if !LOCATIONS.include?(loc_sym)
|
|
35
38
|
raise ArgumentError, "#{self} (#{self.graphql_name}) has an invalid directive location: `locations #{new_loc}` "
|
|
36
39
|
end
|
|
40
|
+
is_runtime ||= RUNTIME_LOCATIONS.include?(loc_sym)
|
|
37
41
|
end
|
|
38
42
|
@locations = new_locations
|
|
43
|
+
@is_runtime = is_runtime
|
|
39
44
|
else
|
|
40
45
|
@locations ||= (superclass.respond_to?(:locations) ? superclass.locations : [])
|
|
41
46
|
end
|
|
42
47
|
end
|
|
43
48
|
|
|
49
|
+
def runtime?
|
|
50
|
+
@is_runtime
|
|
51
|
+
end
|
|
52
|
+
|
|
44
53
|
def default_directive(new_default_directive = nil)
|
|
45
54
|
if new_default_directive != nil
|
|
46
55
|
@default_directive = new_default_directive
|
|
@@ -75,6 +84,10 @@ module GraphQL
|
|
|
75
84
|
yield
|
|
76
85
|
end
|
|
77
86
|
|
|
87
|
+
def validate!(arguments, context)
|
|
88
|
+
Schema::Validator.validate!(validators, self, context, arguments)
|
|
89
|
+
end
|
|
90
|
+
|
|
78
91
|
def on_field?
|
|
79
92
|
locations.include?(FIELD)
|
|
80
93
|
end
|
|
@@ -99,8 +112,12 @@ module GraphQL
|
|
|
99
112
|
|
|
100
113
|
def inherited(subclass)
|
|
101
114
|
super
|
|
102
|
-
|
|
115
|
+
parent_class = self
|
|
116
|
+
subclass.class_exec do
|
|
103
117
|
@default_graphql_name ||= nil
|
|
118
|
+
@locations = parent_class.locations
|
|
119
|
+
@is_runtime = parent_class.runtime?
|
|
120
|
+
@repeatable = false
|
|
104
121
|
end
|
|
105
122
|
end
|
|
106
123
|
end
|
|
@@ -111,6 +128,9 @@ module GraphQL
|
|
|
111
128
|
# @return [GraphQL::Interpreter::Arguments]
|
|
112
129
|
attr_reader :arguments
|
|
113
130
|
|
|
131
|
+
class InvalidArgumentError < GraphQL::Error
|
|
132
|
+
end
|
|
133
|
+
|
|
114
134
|
def initialize(owner, **arguments)
|
|
115
135
|
@owner = owner
|
|
116
136
|
assert_valid_owner
|
|
@@ -119,7 +139,49 @@ module GraphQL
|
|
|
119
139
|
# - lazy resolution
|
|
120
140
|
# Probably, those won't be needed here, since these are configuration arguments,
|
|
121
141
|
# not runtime arguments.
|
|
122
|
-
|
|
142
|
+
context = Query::NullContext.instance
|
|
143
|
+
self.class.all_argument_definitions.each do |arg_defn|
|
|
144
|
+
keyword = arg_defn.keyword
|
|
145
|
+
arg_type = arg_defn.type
|
|
146
|
+
if arguments.key?(keyword)
|
|
147
|
+
value = arguments[keyword]
|
|
148
|
+
# This is a Ruby-land value; convert it to graphql for validation
|
|
149
|
+
graphql_value = begin
|
|
150
|
+
coerce_value = value
|
|
151
|
+
if arg_type.list? && (!coerce_value.nil?) && (!coerce_value.is_a?(Array))
|
|
152
|
+
# When validating inputs, GraphQL accepts a single item
|
|
153
|
+
# and implicitly converts it to a one-item list.
|
|
154
|
+
# However, we're using result coercion here to go from Ruby value
|
|
155
|
+
# to GraphQL value, so it doesn't have that feature.
|
|
156
|
+
# Keep the GraphQL-type behavior but implement it manually:
|
|
157
|
+
wrap_type = arg_type
|
|
158
|
+
while wrap_type.list?
|
|
159
|
+
if wrap_type.non_null?
|
|
160
|
+
wrap_type = wrap_type.of_type
|
|
161
|
+
end
|
|
162
|
+
wrap_type = wrap_type.of_type
|
|
163
|
+
coerce_value = [coerce_value]
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
arg_type.coerce_isolated_result(coerce_value)
|
|
167
|
+
rescue GraphQL::Schema::Enum::UnresolvedValueError
|
|
168
|
+
# Let validation handle this
|
|
169
|
+
value
|
|
170
|
+
end
|
|
171
|
+
else
|
|
172
|
+
value = graphql_value = nil
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
result = arg_type.validate_input(graphql_value, context)
|
|
176
|
+
if !result.valid?
|
|
177
|
+
raise InvalidArgumentError, "@#{graphql_name}.#{arg_defn.graphql_name} on #{owner.path} is invalid (#{value.inspect}): #{result.problems.first["explanation"]}"
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
self.class.validate!(arguments, context)
|
|
181
|
+
@arguments = self.class.coerce_arguments(nil, arguments, context)
|
|
182
|
+
if @arguments.is_a?(GraphQL::ExecutionError)
|
|
183
|
+
raise @arguments
|
|
184
|
+
end
|
|
123
185
|
end
|
|
124
186
|
|
|
125
187
|
def graphql_name
|
|
@@ -127,13 +189,16 @@ module GraphQL
|
|
|
127
189
|
end
|
|
128
190
|
|
|
129
191
|
LOCATIONS = [
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
192
|
+
*(RUNTIME_LOCATIONS = [
|
|
193
|
+
QUERY = :QUERY,
|
|
194
|
+
MUTATION = :MUTATION,
|
|
195
|
+
SUBSCRIPTION = :SUBSCRIPTION,
|
|
196
|
+
FIELD = :FIELD,
|
|
197
|
+
FRAGMENT_DEFINITION = :FRAGMENT_DEFINITION,
|
|
198
|
+
FRAGMENT_SPREAD = :FRAGMENT_SPREAD,
|
|
199
|
+
INLINE_FRAGMENT = :INLINE_FRAGMENT,
|
|
200
|
+
VARIABLE_DEFINITION = :VARIABLE_DEFINITION,
|
|
201
|
+
]),
|
|
137
202
|
SCHEMA = :SCHEMA,
|
|
138
203
|
SCALAR = :SCALAR,
|
|
139
204
|
OBJECT = :OBJECT,
|
|
@@ -145,7 +210,6 @@ module GraphQL
|
|
|
145
210
|
ENUM_VALUE = :ENUM_VALUE,
|
|
146
211
|
INPUT_OBJECT = :INPUT_OBJECT,
|
|
147
212
|
INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
|
|
148
|
-
VARIABLE_DEFINITION = :VARIABLE_DEFINITION,
|
|
149
213
|
]
|
|
150
214
|
|
|
151
215
|
DEFAULT_DEPRECATION_REASON = 'No longer supported'
|
|
@@ -188,6 +252,8 @@ module GraphQL
|
|
|
188
252
|
assert_has_location(SCALAR)
|
|
189
253
|
elsif @owner < GraphQL::Schema
|
|
190
254
|
assert_has_location(SCHEMA)
|
|
255
|
+
elsif @owner < GraphQL::Schema::Resolver
|
|
256
|
+
assert_has_location(FIELD_DEFINITION)
|
|
191
257
|
else
|
|
192
258
|
raise "Unexpected directive owner class: #{@owner}"
|
|
193
259
|
end
|