graphql 0.16.0 → 2.0.15
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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.yardopts +5 -0
- data/lib/generators/graphql/core.rb +69 -0
- data/lib/generators/graphql/enum_generator.rb +27 -0
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/install/templates/base_mutation.erb +10 -0
- data/lib/generators/graphql/install/templates/mutation_type.erb +12 -0
- data/lib/generators/graphql/install_generator.rb +197 -0
- data/lib/generators/graphql/interface_generator.rb +27 -0
- data/lib/generators/graphql/loader_generator.rb +21 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +30 -0
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +50 -0
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +49 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +22 -0
- data/lib/generators/graphql/templates/base_argument.erb +6 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +6 -0
- data/lib/generators/graphql/templates/base_field.erb +7 -0
- data/lib/generators/graphql/templates/base_input_object.erb +7 -0
- data/lib/generators/graphql/templates/base_interface.erb +9 -0
- data/lib/generators/graphql/templates/base_object.erb +7 -0
- data/lib/generators/graphql/templates/base_scalar.erb +6 -0
- data/lib/generators/graphql/templates/base_union.erb +6 -0
- data/lib/generators/graphql/templates/enum.erb +11 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +52 -0
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +10 -0
- data/lib/generators/graphql/templates/loader.erb +19 -0
- data/lib/generators/graphql/templates/mutation.erb +16 -0
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +10 -0
- data/lib/generators/graphql/templates/query_type.erb +15 -0
- data/lib/generators/graphql/templates/scalar.erb +17 -0
- data/lib/generators/graphql/templates/schema.erb +30 -0
- data/lib/generators/graphql/templates/union.erb +9 -0
- data/lib/generators/graphql/type_generator.rb +135 -0
- data/lib/generators/graphql/union_generator.rb +33 -0
- data/lib/graphql/analysis/ast/analyzer.rb +84 -0
- data/lib/graphql/analysis/ast/field_usage.rb +57 -0
- data/lib/graphql/analysis/ast/max_query_complexity.rb +22 -0
- data/lib/graphql/analysis/ast/max_query_depth.rb +22 -0
- data/lib/graphql/analysis/ast/query_complexity.rb +230 -0
- data/lib/graphql/analysis/ast/query_depth.rb +55 -0
- data/lib/graphql/analysis/ast/visitor.rb +269 -0
- data/lib/graphql/analysis/ast.rb +81 -0
- data/lib/graphql/analysis.rb +2 -5
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/backtrace/inspect_result.rb +50 -0
- data/lib/graphql/backtrace/table.rb +141 -0
- data/lib/graphql/backtrace/traced_error.rb +54 -0
- data/lib/graphql/backtrace/tracer.rb +80 -0
- data/lib/graphql/backtrace.rb +58 -0
- data/lib/graphql/coercion_error.rb +13 -0
- data/lib/graphql/dataloader/null_dataloader.rb +24 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +164 -0
- data/lib/graphql/dataloader.rb +311 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +19 -0
- data/lib/graphql/execution/directive_checks.rb +37 -0
- data/lib/graphql/execution/errors.rb +93 -0
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
- data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +77 -0
- data/lib/graphql/execution/interpreter/runtime.rb +994 -0
- data/lib/graphql/execution/interpreter.rb +226 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +98 -0
- data/lib/graphql/execution/lazy.rb +75 -0
- data/lib/graphql/execution/lookahead.rb +311 -0
- data/lib/graphql/execution/multiplex.rb +45 -0
- data/lib/graphql/execution.rb +18 -0
- data/lib/graphql/execution_error.rb +34 -1
- data/lib/graphql/filter.rb +53 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +36 -0
- data/lib/graphql/introspection/base_object.rb +13 -0
- data/lib/graphql/introspection/directive_location_enum.rb +12 -5
- data/lib/graphql/introspection/directive_type.rb +30 -10
- data/lib/graphql/introspection/dynamic_fields.rb +12 -0
- data/lib/graphql/introspection/entry_points.rb +22 -0
- data/lib/graphql/introspection/enum_value_type.rb +21 -8
- data/lib/graphql/introspection/field_type.rb +26 -10
- data/lib/graphql/introspection/input_value_type.rb +64 -14
- data/lib/graphql/introspection/introspection_query.rb +7 -76
- data/lib/graphql/introspection/schema_type.rb +42 -17
- data/lib/graphql/introspection/type_kind_enum.rb +11 -5
- data/lib/graphql/introspection/type_type.rb +104 -16
- data/lib/graphql/introspection.rb +104 -13
- data/lib/graphql/invalid_name_error.rb +11 -0
- data/lib/graphql/invalid_null_error.rb +36 -8
- data/lib/graphql/language/block_string.rb +99 -0
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +41 -0
- data/lib/graphql/language/document_from_schema_definition.rb +335 -0
- data/lib/graphql/language/generation.rb +16 -86
- data/lib/graphql/language/lexer.rb +1436 -705
- data/lib/graphql/language/lexer.rl +172 -64
- data/lib/graphql/language/nodes.rb +617 -105
- data/lib/graphql/language/parser.rb +1524 -430
- data/lib/graphql/language/parser.y +348 -73
- data/lib/graphql/language/printer.rb +386 -0
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +16 -3
- data/lib/graphql/language/visitor.rb +169 -25
- data/lib/graphql/language.rb +30 -0
- data/lib/graphql/load_application_object_failed_error.rb +22 -0
- data/lib/graphql/name_validator.rb +11 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
- data/lib/graphql/pagination/array_connection.rb +79 -0
- data/lib/graphql/pagination/connection.rb +253 -0
- data/lib/graphql/pagination/connections.rb +135 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +228 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/parse_error.rb +24 -0
- data/lib/graphql/query/context.rb +266 -12
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +34 -7
- data/lib/graphql/query/null_context.rb +52 -0
- data/lib/graphql/query/result.rb +63 -0
- data/lib/graphql/query/validation_pipeline.rb +114 -0
- data/lib/graphql/query/variable_validation_error.rb +27 -3
- data/lib/graphql/query/variables.rb +75 -24
- data/lib/graphql/query.rb +359 -92
- data/lib/graphql/railtie.rb +13 -0
- data/lib/graphql/rake_task/validate.rb +63 -0
- data/lib/graphql/rake_task.rb +146 -0
- data/lib/graphql/relay/range_add.rb +52 -0
- data/lib/graphql/relay.rb +3 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/runtime_type_error.rb +5 -0
- data/lib/graphql/schema/addition.rb +245 -0
- data/lib/graphql/schema/argument.rb +395 -0
- data/lib/graphql/schema/base_64_bp.rb +26 -0
- data/lib/graphql/schema/base_64_encoder.rb +21 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +47 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +78 -0
- data/lib/graphql/schema/build_from_definition.rb +492 -0
- data/lib/graphql/schema/built_in_types.rb +12 -0
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/feature.rb +66 -0
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +25 -0
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +25 -0
- data/lib/graphql/schema/directive/transform.rb +60 -0
- data/lib/graphql/schema/directive.rb +212 -0
- data/lib/graphql/schema/enum.rb +176 -0
- data/lib/graphql/schema/enum_value.rb +77 -0
- data/lib/graphql/schema/field/connection_extension.rb +80 -0
- data/lib/graphql/schema/field/scope_extension.rb +22 -0
- data/lib/graphql/schema/field.rb +862 -0
- data/lib/graphql/schema/field_extension.rb +156 -0
- data/lib/graphql/schema/find_inherited_value.rb +36 -0
- data/lib/graphql/schema/finder.rb +155 -0
- data/lib/graphql/schema/input_object.rb +258 -0
- data/lib/graphql/schema/interface.rb +113 -0
- data/lib/graphql/schema/introspection_system.rb +164 -0
- data/lib/graphql/schema/invalid_type_error.rb +1 -0
- data/lib/graphql/schema/late_bound_type.rb +37 -0
- data/lib/graphql/schema/list.rb +86 -0
- data/lib/graphql/schema/loader.rb +228 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +124 -0
- data/lib/graphql/schema/member/build_type.rb +178 -0
- data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
- data/lib/graphql/schema/member/has_arguments.rb +376 -0
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +113 -0
- data/lib/graphql/schema/member/has_fields.rb +163 -0
- data/lib/graphql/schema/member/has_interfaces.rb +88 -0
- data/lib/graphql/schema/member/has_path.rb +25 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +73 -0
- data/lib/graphql/schema/member/scoped.rb +21 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +38 -0
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +39 -0
- data/lib/graphql/schema/mutation.rb +85 -0
- data/lib/graphql/schema/non_null.rb +67 -0
- data/lib/graphql/schema/null_mask.rb +11 -0
- data/lib/graphql/schema/object.rb +117 -0
- data/lib/graphql/schema/printer.rb +72 -128
- data/lib/graphql/schema/relay_classic_mutation.rb +179 -0
- data/lib/graphql/schema/resolver/has_payload_type.rb +106 -0
- data/lib/graphql/schema/resolver.rb +402 -0
- data/lib/graphql/schema/scalar.rb +68 -0
- data/lib/graphql/schema/subscription.rb +148 -0
- data/lib/graphql/schema/timeout.rb +123 -0
- data/lib/graphql/schema/type_expression.rb +29 -5
- data/lib/graphql/schema/type_membership.rb +51 -0
- data/lib/graphql/schema/union.rb +81 -0
- data/lib/graphql/schema/unique_within_type.rb +34 -0
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +413 -0
- data/lib/graphql/schema/wrapper.rb +24 -0
- data/lib/graphql/schema.rb +1179 -104
- data/lib/graphql/static_validation/all_rules.rb +14 -0
- data/lib/graphql/static_validation/base_visitor.rb +200 -0
- data/lib/graphql/static_validation/definition_dependencies.rb +198 -0
- data/lib/graphql/static_validation/error.rb +46 -0
- data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
- data/lib/graphql/static_validation/literal_validator.rb +113 -22
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +59 -11
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +48 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +31 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +62 -8
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +37 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +20 -13
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +32 -26
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +21 -23
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +55 -18
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +390 -70
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +53 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +54 -37
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +26 -16
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +13 -19
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +16 -0
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +22 -33
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +41 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +36 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +22 -21
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +59 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +56 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +36 -18
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +24 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +103 -39
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +22 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +92 -70
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
- data/lib/graphql/static_validation/type_stack.rb +85 -24
- data/lib/graphql/static_validation/validation_context.rb +25 -46
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +46 -15
- data/lib/graphql/static_validation.rb +6 -3
- data/lib/graphql/string_encoding_error.rb +20 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +247 -0
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +144 -0
- data/lib/graphql/subscriptions/instrumentation.rb +28 -0
- data/lib/graphql/subscriptions/serialize.rb +158 -0
- data/lib/graphql/subscriptions.rb +306 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +21 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +51 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +100 -0
- data/lib/graphql/tracing/instrumentation_tracing.rb +83 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +51 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +122 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +32 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +67 -0
- data/lib/graphql/tracing/scout_tracing.rb +54 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +94 -0
- data/lib/graphql/type_kinds.rb +50 -22
- data/lib/graphql/types/big_int.rb +23 -0
- data/lib/graphql/types/boolean.rb +18 -0
- data/lib/graphql/types/float.rb +19 -0
- data/lib/graphql/types/id.rb +24 -0
- data/lib/graphql/types/int.rb +36 -0
- data/lib/graphql/types/iso_8601_date.rb +45 -0
- data/lib/graphql/types/iso_8601_date_time.rb +76 -0
- data/lib/graphql/types/json.rb +25 -0
- data/lib/graphql/types/relay/base_connection.rb +49 -0
- data/lib/graphql/types/relay/base_edge.rb +29 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +154 -0
- data/lib/graphql/types/relay/default_relay.rb +21 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +15 -0
- data/lib/graphql/types/relay/node_behaviors.rb +19 -0
- data/lib/graphql/types/relay/page_info.rb +11 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +39 -0
- data/lib/graphql/types/string.rb +29 -0
- data/lib/graphql/types.rb +11 -0
- data/lib/graphql/unauthorized_error.rb +29 -0
- data/lib/graphql/unauthorized_field_error.rb +23 -0
- data/lib/graphql/unresolved_type_error.rb +35 -0
- data/lib/graphql/version.rb +2 -1
- data/lib/graphql.rb +86 -41
- data/readme.md +15 -101
- metadata +394 -279
- data/lib/graphql/analysis/analyze_query.rb +0 -73
- data/lib/graphql/analysis/max_query_complexity.rb +0 -25
- data/lib/graphql/analysis/max_query_depth.rb +0 -25
- data/lib/graphql/analysis/query_complexity.rb +0 -122
- data/lib/graphql/analysis/query_depth.rb +0 -54
- data/lib/graphql/argument.rb +0 -25
- data/lib/graphql/base_type.rb +0 -115
- data/lib/graphql/boolean_type.rb +0 -9
- data/lib/graphql/define/assign_argument.rb +0 -20
- data/lib/graphql/define/assign_enum_value.rb +0 -16
- data/lib/graphql/define/assign_object_field.rb +0 -21
- data/lib/graphql/define/assignment_dictionary.rb +0 -26
- data/lib/graphql/define/defined_object_proxy.rb +0 -32
- data/lib/graphql/define/instance_definable.rb +0 -79
- data/lib/graphql/define/non_null_with_bang.rb +0 -15
- data/lib/graphql/define/type_definer.rb +0 -30
- data/lib/graphql/define.rb +0 -8
- data/lib/graphql/directive/include_directive.rb +0 -10
- data/lib/graphql/directive/skip_directive.rb +0 -11
- data/lib/graphql/directive.rb +0 -49
- data/lib/graphql/enum_type.rb +0 -95
- data/lib/graphql/field.rb +0 -131
- data/lib/graphql/float_type.rb +0 -5
- data/lib/graphql/id_type.rb +0 -12
- data/lib/graphql/input_object_type.rb +0 -71
- data/lib/graphql/int_type.rb +0 -5
- data/lib/graphql/interface_type.rb +0 -38
- data/lib/graphql/internal_representation/node.rb +0 -81
- data/lib/graphql/internal_representation/rewrite.rb +0 -177
- data/lib/graphql/internal_representation.rb +0 -2
- data/lib/graphql/introspection/arguments_field.rb +0 -5
- data/lib/graphql/introspection/enum_values_field.rb +0 -13
- data/lib/graphql/introspection/fields_field.rb +0 -13
- data/lib/graphql/introspection/input_fields_field.rb +0 -12
- data/lib/graphql/introspection/interfaces_field.rb +0 -5
- data/lib/graphql/introspection/of_type_field.rb +0 -6
- data/lib/graphql/introspection/possible_types_field.rb +0 -11
- data/lib/graphql/introspection/schema_field.rb +0 -15
- data/lib/graphql/introspection/type_by_name_field.rb +0 -16
- data/lib/graphql/introspection/typename_field.rb +0 -15
- data/lib/graphql/list_type.rb +0 -46
- data/lib/graphql/non_null_type.rb +0 -43
- data/lib/graphql/object_type.rb +0 -93
- data/lib/graphql/query/arguments.rb +0 -76
- data/lib/graphql/query/directive_resolution.rb +0 -16
- data/lib/graphql/query/executor.rb +0 -45
- data/lib/graphql/query/literal_input.rb +0 -90
- data/lib/graphql/query/serial_execution/execution_context.rb +0 -31
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -82
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -27
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -42
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -107
- data/lib/graphql/query/serial_execution.rb +0 -41
- data/lib/graphql/query/type_resolver.rb +0 -25
- data/lib/graphql/scalar_type.rb +0 -53
- data/lib/graphql/schema/catchall_middleware.rb +0 -34
- data/lib/graphql/schema/middleware_chain.rb +0 -28
- data/lib/graphql/schema/possible_types.rb +0 -34
- data/lib/graphql/schema/reduce_types.rb +0 -68
- data/lib/graphql/schema/rescue_middleware.rb +0 -53
- data/lib/graphql/schema/timeout_middleware.rb +0 -67
- data/lib/graphql/schema/type_map.rb +0 -30
- data/lib/graphql/schema/validation.rb +0 -164
- data/lib/graphql/static_validation/arguments_validator.rb +0 -48
- data/lib/graphql/static_validation/message.rb +0 -36
- data/lib/graphql/string_type.rb +0 -5
- data/lib/graphql/union_type.rb +0 -38
- data/spec/graphql/analysis/analyze_query_spec.rb +0 -50
- data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -62
- data/spec/graphql/analysis/max_query_depth_spec.rb +0 -100
- data/spec/graphql/analysis/query_complexity_spec.rb +0 -235
- data/spec/graphql/analysis/query_depth_spec.rb +0 -80
- data/spec/graphql/argument_spec.rb +0 -20
- data/spec/graphql/base_type_spec.rb +0 -24
- data/spec/graphql/boolean_type_spec.rb +0 -20
- data/spec/graphql/define/instance_definable_spec.rb +0 -55
- data/spec/graphql/directive_spec.rb +0 -77
- data/spec/graphql/enum_type_spec.rb +0 -31
- data/spec/graphql/execution_error_spec.rb +0 -61
- data/spec/graphql/field_spec.rb +0 -92
- data/spec/graphql/float_type_spec.rb +0 -15
- data/spec/graphql/id_type_spec.rb +0 -32
- data/spec/graphql/input_object_type_spec.rb +0 -162
- data/spec/graphql/int_type_spec.rb +0 -15
- data/spec/graphql/interface_type_spec.rb +0 -56
- data/spec/graphql/internal_representation/rewrite_spec.rb +0 -120
- data/spec/graphql/introspection/directive_type_spec.rb +0 -50
- data/spec/graphql/introspection/input_value_type_spec.rb +0 -42
- data/spec/graphql/introspection/introspection_query_spec.rb +0 -10
- data/spec/graphql/introspection/schema_type_spec.rb +0 -45
- data/spec/graphql/introspection/type_type_spec.rb +0 -122
- data/spec/graphql/language/generation_spec.rb +0 -42
- data/spec/graphql/language/parser_spec.rb +0 -442
- data/spec/graphql/language/visitor_spec.rb +0 -49
- data/spec/graphql/list_type_spec.rb +0 -32
- data/spec/graphql/non_null_type_spec.rb +0 -31
- data/spec/graphql/object_type_spec.rb +0 -42
- data/spec/graphql/query/arguments_spec.rb +0 -25
- data/spec/graphql/query/context_spec.rb +0 -83
- data/spec/graphql/query/executor_spec.rb +0 -273
- data/spec/graphql/query/serial_execution/execution_context_spec.rb +0 -53
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -66
- data/spec/graphql/query/type_resolver_spec.rb +0 -8
- data/spec/graphql/query/variables_spec.rb +0 -28
- data/spec/graphql/query_spec.rb +0 -363
- data/spec/graphql/scalar_type_spec.rb +0 -61
- data/spec/graphql/schema/catchall_middleware_spec.rb +0 -32
- data/spec/graphql/schema/middleware_chain_spec.rb +0 -42
- data/spec/graphql/schema/printer_spec.rb +0 -190
- data/spec/graphql/schema/reduce_types_spec.rb +0 -102
- data/spec/graphql/schema/rescue_middleware_spec.rb +0 -33
- data/spec/graphql/schema/timeout_middleware_spec.rb +0 -180
- data/spec/graphql/schema/type_expression_spec.rb +0 -38
- data/spec/graphql/schema/validation_spec.rb +0 -219
- data/spec/graphql/schema_spec.rb +0 -23
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -63
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -48
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -34
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -39
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -60
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -31
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -48
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -47
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -39
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -44
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -49
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -25
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -42
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -44
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -63
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -37
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -53
- data/spec/graphql/static_validation/type_stack_spec.rb +0 -37
- data/spec/graphql/static_validation/validator_spec.rb +0 -69
- data/spec/graphql/string_type_spec.rb +0 -15
- data/spec/graphql/union_type_spec.rb +0 -31
- data/spec/spec_helper.rb +0 -18
- data/spec/support/dairy_app.rb +0 -309
- data/spec/support/dairy_data.rb +0 -23
- data/spec/support/minimum_input_object.rb +0 -16
- data/spec/support/star_wars_data.rb +0 -71
- data/spec/support/star_wars_schema.rb +0 -76
@@ -0,0 +1,492 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "graphql/schema/build_from_definition/resolve_map"
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
class Schema
|
6
|
+
module BuildFromDefinition
|
7
|
+
class << self
|
8
|
+
# @see {Schema.from_definition}
|
9
|
+
def from_definition(schema_superclass, definition_string, parser: GraphQL.default_parser, **kwargs)
|
10
|
+
from_document(schema_superclass, parser.parse(definition_string), **kwargs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def from_definition_path(schema_superclass, definition_path, parser: GraphQL.default_parser, **kwargs)
|
14
|
+
from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
|
15
|
+
end
|
16
|
+
|
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)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
module Builder
|
24
|
+
extend self
|
25
|
+
|
26
|
+
def build(schema_superclass, document, default_resolve:, using: {}, relay:)
|
27
|
+
raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
|
28
|
+
|
29
|
+
if default_resolve.is_a?(Hash)
|
30
|
+
default_resolve = ResolveMap.new(default_resolve)
|
31
|
+
end
|
32
|
+
|
33
|
+
schema_defns = document.definitions.select { |d| d.is_a?(GraphQL::Language::Nodes::SchemaDefinition) }
|
34
|
+
if schema_defns.size > 1
|
35
|
+
raise InvalidDocumentError.new('Must provide only one schema definition.')
|
36
|
+
end
|
37
|
+
schema_definition = schema_defns.first
|
38
|
+
types = {}
|
39
|
+
directives = schema_superclass.directives.dup
|
40
|
+
type_resolver = build_resolve_type(types, directives, ->(type_name) { types[type_name] ||= Schema::LateBoundType.new(type_name)})
|
41
|
+
# Make a different type resolver because we need to coerce directive arguments
|
42
|
+
# _while_ building the schema.
|
43
|
+
# It will dig for a type if it encounters a custom type. This could be a problem if there are cycles.
|
44
|
+
directive_type_resolver = nil
|
45
|
+
directive_type_resolver = build_resolve_type(types, directives, ->(type_name) {
|
46
|
+
types[type_name] ||= begin
|
47
|
+
defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
|
48
|
+
if defn
|
49
|
+
build_definition_from_node(defn, directive_type_resolver, default_resolve)
|
50
|
+
elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
|
51
|
+
built_in_defn
|
52
|
+
else
|
53
|
+
raise "No definition for #{type_name.inspect} found in schema document or built-in types. Add a definition for it or remove it."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
})
|
57
|
+
|
58
|
+
directives.merge!(GraphQL::Schema.default_directives)
|
59
|
+
document.definitions.each do |definition|
|
60
|
+
if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
|
61
|
+
directives[definition.name] = build_directive(definition, directive_type_resolver)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# In case any directives referenced built-in types for their arguments:
|
66
|
+
replace_late_bound_types_with_built_in(types)
|
67
|
+
|
68
|
+
schema_extensions = nil
|
69
|
+
document.definitions.each do |definition|
|
70
|
+
case definition
|
71
|
+
when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
|
72
|
+
nil # already handled
|
73
|
+
when GraphQL::Language::Nodes::SchemaExtension
|
74
|
+
schema_extensions ||= []
|
75
|
+
schema_extensions << definition
|
76
|
+
else
|
77
|
+
# It's possible that this was already loaded by the directives
|
78
|
+
prev_type = types[definition.name]
|
79
|
+
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
|
80
|
+
types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
replace_late_bound_types_with_built_in(types)
|
86
|
+
|
87
|
+
if schema_definition
|
88
|
+
if schema_definition.query
|
89
|
+
raise InvalidDocumentError.new("Specified query type \"#{schema_definition.query}\" not found in document.") unless types[schema_definition.query]
|
90
|
+
query_root_type = types[schema_definition.query]
|
91
|
+
end
|
92
|
+
|
93
|
+
if schema_definition.mutation
|
94
|
+
raise InvalidDocumentError.new("Specified mutation type \"#{schema_definition.mutation}\" not found in document.") unless types[schema_definition.mutation]
|
95
|
+
mutation_root_type = types[schema_definition.mutation]
|
96
|
+
end
|
97
|
+
|
98
|
+
if schema_definition.subscription
|
99
|
+
raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
|
100
|
+
subscription_root_type = types[schema_definition.subscription]
|
101
|
+
end
|
102
|
+
else
|
103
|
+
query_root_type = types['Query']
|
104
|
+
mutation_root_type = types['Mutation']
|
105
|
+
subscription_root_type = types['Subscription']
|
106
|
+
end
|
107
|
+
|
108
|
+
raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
|
109
|
+
|
110
|
+
schema_class = Class.new(schema_superclass) do
|
111
|
+
begin
|
112
|
+
# Add these first so that there's some chance of resolving late-bound types
|
113
|
+
orphan_types types.values
|
114
|
+
query query_root_type
|
115
|
+
mutation mutation_root_type
|
116
|
+
subscription subscription_root_type
|
117
|
+
rescue Schema::UnresolvedLateBoundTypeError => err
|
118
|
+
type_name = err.type.name
|
119
|
+
err_backtrace = err.backtrace
|
120
|
+
raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
|
121
|
+
end
|
122
|
+
|
123
|
+
if default_resolve.respond_to?(:resolve_type)
|
124
|
+
def self.resolve_type(*args)
|
125
|
+
self.definition_default_resolve.resolve_type(*args)
|
126
|
+
end
|
127
|
+
else
|
128
|
+
def self.resolve_type(*args)
|
129
|
+
NullResolveType.call(*args)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
directives directives.values
|
134
|
+
|
135
|
+
if schema_definition
|
136
|
+
ast_node(schema_definition)
|
137
|
+
end
|
138
|
+
|
139
|
+
using.each do |plugin, options|
|
140
|
+
if options
|
141
|
+
use(plugin, **options)
|
142
|
+
else
|
143
|
+
use(plugin)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Empty `orphan_types` -- this will make unreachable types ... unreachable.
|
148
|
+
own_orphan_types.clear
|
149
|
+
|
150
|
+
class << self
|
151
|
+
attr_accessor :definition_default_resolve
|
152
|
+
end
|
153
|
+
|
154
|
+
self.definition_default_resolve = default_resolve
|
155
|
+
|
156
|
+
def definition_default_resolve
|
157
|
+
self.class.definition_default_resolve
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.inherited(child_class)
|
161
|
+
child_class.definition_default_resolve = self.definition_default_resolve
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
if schema_extensions
|
166
|
+
schema_extensions.each do |ext|
|
167
|
+
build_directives(schema_class, ext, type_resolver)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
schema_class
|
172
|
+
end
|
173
|
+
|
174
|
+
NullResolveType = ->(type, obj, ctx) {
|
175
|
+
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
|
176
|
+
}
|
177
|
+
|
178
|
+
def build_definition_from_node(definition, type_resolver, default_resolve)
|
179
|
+
case definition
|
180
|
+
when GraphQL::Language::Nodes::EnumTypeDefinition
|
181
|
+
build_enum_type(definition, type_resolver)
|
182
|
+
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
183
|
+
build_object_type(definition, type_resolver)
|
184
|
+
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
185
|
+
build_interface_type(definition, type_resolver)
|
186
|
+
when GraphQL::Language::Nodes::UnionTypeDefinition
|
187
|
+
build_union_type(definition, type_resolver)
|
188
|
+
when GraphQL::Language::Nodes::ScalarTypeDefinition
|
189
|
+
build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
|
190
|
+
when GraphQL::Language::Nodes::InputObjectTypeDefinition
|
191
|
+
build_input_object_type(definition, type_resolver)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Modify `types`, replacing any late-bound references to built-in types
|
196
|
+
# with their actual definitions.
|
197
|
+
#
|
198
|
+
# (Schema definitions are allowed to reference those built-ins without redefining them.)
|
199
|
+
# @return void
|
200
|
+
def replace_late_bound_types_with_built_in(types)
|
201
|
+
GraphQL::Schema::BUILT_IN_TYPES.each do |scalar_name, built_in_scalar|
|
202
|
+
existing_type = types[scalar_name]
|
203
|
+
if existing_type.is_a?(GraphQL::Schema::LateBoundType)
|
204
|
+
types[scalar_name] = built_in_scalar
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def build_directives(definition, ast_node, type_resolver)
|
210
|
+
dirs = prepare_directives(ast_node, type_resolver)
|
211
|
+
dirs.each do |(dir_class, options)|
|
212
|
+
if definition.respond_to?(:schema_directive)
|
213
|
+
# it's a schema
|
214
|
+
definition.schema_directive(dir_class, **options)
|
215
|
+
else
|
216
|
+
definition.directive(dir_class, **options)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def prepare_directives(ast_node, type_resolver)
|
222
|
+
dirs = []
|
223
|
+
ast_node.directives.each do |dir_node|
|
224
|
+
if dir_node.name == "deprecated"
|
225
|
+
# This is handled using `deprecation_reason`
|
226
|
+
next
|
227
|
+
else
|
228
|
+
dir_class = type_resolver.call(dir_node.name)
|
229
|
+
if dir_class.nil?
|
230
|
+
raise ArgumentError, "No definition for @#{dir_node.name} #{ast_node.respond_to?(:name) ? "on #{ast_node.name} " : ""}at #{ast_node.line}:#{ast_node.col}"
|
231
|
+
end
|
232
|
+
options = args_to_kwargs(dir_class, dir_node)
|
233
|
+
dirs << [dir_class, options]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
dirs
|
237
|
+
end
|
238
|
+
|
239
|
+
def args_to_kwargs(arg_owner, node)
|
240
|
+
if node.respond_to?(:arguments)
|
241
|
+
kwargs = {}
|
242
|
+
node.arguments.each do |arg_node|
|
243
|
+
arg_defn = arg_owner.get_argument(arg_node.name)
|
244
|
+
kwargs[arg_defn.keyword] = args_to_kwargs(arg_defn.type.unwrap, arg_node.value)
|
245
|
+
end
|
246
|
+
kwargs
|
247
|
+
elsif node.is_a?(Array)
|
248
|
+
node.map { |n| args_to_kwargs(arg_owner, n) }
|
249
|
+
elsif node.is_a?(Language::Nodes::Enum)
|
250
|
+
node.name
|
251
|
+
else
|
252
|
+
# scalar
|
253
|
+
node
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def build_enum_type(enum_type_definition, type_resolver)
|
258
|
+
builder = self
|
259
|
+
Class.new(GraphQL::Schema::Enum) do
|
260
|
+
graphql_name(enum_type_definition.name)
|
261
|
+
builder.build_directives(self, enum_type_definition, type_resolver)
|
262
|
+
description(enum_type_definition.description)
|
263
|
+
ast_node(enum_type_definition)
|
264
|
+
enum_type_definition.values.each do |enum_value_definition|
|
265
|
+
value(enum_value_definition.name,
|
266
|
+
value: enum_value_definition.name,
|
267
|
+
deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
|
268
|
+
description: enum_value_definition.description,
|
269
|
+
directives: builder.prepare_directives(enum_value_definition, type_resolver),
|
270
|
+
ast_node: enum_value_definition,
|
271
|
+
)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def build_deprecation_reason(directives)
|
277
|
+
deprecated_directive = directives.find{ |d| d.name == 'deprecated' }
|
278
|
+
return unless deprecated_directive
|
279
|
+
|
280
|
+
reason = deprecated_directive.arguments.find{ |a| a.name == 'reason' }
|
281
|
+
return GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON unless reason
|
282
|
+
|
283
|
+
reason.value
|
284
|
+
end
|
285
|
+
|
286
|
+
def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
|
287
|
+
builder = self
|
288
|
+
Class.new(GraphQL::Schema::Scalar) do
|
289
|
+
graphql_name(scalar_type_definition.name)
|
290
|
+
description(scalar_type_definition.description)
|
291
|
+
ast_node(scalar_type_definition)
|
292
|
+
builder.build_directives(self, scalar_type_definition, type_resolver)
|
293
|
+
|
294
|
+
if default_resolve.respond_to?(:coerce_input)
|
295
|
+
# Put these method definitions in another method to avoid retaining `type_resolve`
|
296
|
+
# from this method's bindiing
|
297
|
+
builder.build_scalar_type_coerce_method(self, :coerce_input, default_resolve)
|
298
|
+
builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
|
304
|
+
scalar_class.define_singleton_method(method_name) do |val, ctx|
|
305
|
+
default_definition_resolve.public_send(method_name, self, val, ctx)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def build_union_type(union_type_definition, type_resolver)
|
310
|
+
builder = self
|
311
|
+
Class.new(GraphQL::Schema::Union) do
|
312
|
+
graphql_name(union_type_definition.name)
|
313
|
+
description(union_type_definition.description)
|
314
|
+
possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
|
315
|
+
ast_node(union_type_definition)
|
316
|
+
builder.build_directives(self, union_type_definition, type_resolver)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def build_object_type(object_type_definition, type_resolver)
|
321
|
+
builder = self
|
322
|
+
|
323
|
+
Class.new(GraphQL::Schema::Object) do
|
324
|
+
graphql_name(object_type_definition.name)
|
325
|
+
description(object_type_definition.description)
|
326
|
+
ast_node(object_type_definition)
|
327
|
+
builder.build_directives(self, object_type_definition, type_resolver)
|
328
|
+
|
329
|
+
object_type_definition.interfaces.each do |interface_name|
|
330
|
+
interface_defn = type_resolver.call(interface_name)
|
331
|
+
implements(interface_defn)
|
332
|
+
end
|
333
|
+
|
334
|
+
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def build_input_object_type(input_object_type_definition, type_resolver)
|
339
|
+
builder = self
|
340
|
+
Class.new(GraphQL::Schema::InputObject) do
|
341
|
+
graphql_name(input_object_type_definition.name)
|
342
|
+
description(input_object_type_definition.description)
|
343
|
+
ast_node(input_object_type_definition)
|
344
|
+
builder.build_directives(self, input_object_type_definition, type_resolver)
|
345
|
+
builder.build_arguments(self, input_object_type_definition.fields, type_resolver)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def build_default_value(default_value)
|
350
|
+
case default_value
|
351
|
+
when GraphQL::Language::Nodes::Enum
|
352
|
+
default_value.name
|
353
|
+
when GraphQL::Language::Nodes::NullValue
|
354
|
+
nil
|
355
|
+
when GraphQL::Language::Nodes::InputObject
|
356
|
+
default_value.to_h
|
357
|
+
when Array
|
358
|
+
default_value.map { |v| build_default_value(v) }
|
359
|
+
else
|
360
|
+
default_value
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
NO_DEFAULT_VALUE = {}.freeze
|
365
|
+
|
366
|
+
def build_arguments(type_class, arguments, type_resolver)
|
367
|
+
builder = self
|
368
|
+
|
369
|
+
arguments.each do |argument_defn|
|
370
|
+
default_value_kwargs = if !argument_defn.default_value.nil?
|
371
|
+
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
372
|
+
else
|
373
|
+
NO_DEFAULT_VALUE
|
374
|
+
end
|
375
|
+
|
376
|
+
type_class.argument(
|
377
|
+
argument_defn.name,
|
378
|
+
type: type_resolver.call(argument_defn.type),
|
379
|
+
required: false,
|
380
|
+
description: argument_defn.description,
|
381
|
+
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
382
|
+
ast_node: argument_defn,
|
383
|
+
camelize: false,
|
384
|
+
directives: prepare_directives(argument_defn, type_resolver),
|
385
|
+
**default_value_kwargs
|
386
|
+
)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
def build_directive(directive_definition, type_resolver)
|
391
|
+
builder = self
|
392
|
+
Class.new(GraphQL::Schema::Directive) do
|
393
|
+
graphql_name(directive_definition.name)
|
394
|
+
description(directive_definition.description)
|
395
|
+
repeatable(directive_definition.repeatable)
|
396
|
+
locations(*directive_definition.locations.map { |location| location.name.to_sym })
|
397
|
+
ast_node(directive_definition)
|
398
|
+
builder.build_arguments(self, directive_definition.arguments, type_resolver)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
def build_interface_type(interface_type_definition, type_resolver)
|
403
|
+
builder = self
|
404
|
+
Module.new do
|
405
|
+
include GraphQL::Schema::Interface
|
406
|
+
graphql_name(interface_type_definition.name)
|
407
|
+
description(interface_type_definition.description)
|
408
|
+
interface_type_definition.interfaces.each do |interface_name|
|
409
|
+
interface_defn = type_resolver.call(interface_name)
|
410
|
+
implements(interface_defn)
|
411
|
+
end
|
412
|
+
ast_node(interface_type_definition)
|
413
|
+
builder.build_directives(self, interface_type_definition, type_resolver)
|
414
|
+
|
415
|
+
builder.build_fields(self, interface_type_definition.fields, type_resolver, default_resolve: nil)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
|
420
|
+
builder = self
|
421
|
+
|
422
|
+
field_definitions.each do |field_definition|
|
423
|
+
type_name = resolve_type_name(field_definition.type)
|
424
|
+
resolve_method_name = -"resolve_field_#{field_definition.name}"
|
425
|
+
schema_field_defn = owner.field(
|
426
|
+
field_definition.name,
|
427
|
+
description: field_definition.description,
|
428
|
+
type: type_resolver.call(field_definition.type),
|
429
|
+
null: true,
|
430
|
+
connection: type_name.end_with?("Connection"),
|
431
|
+
connection_extension: nil,
|
432
|
+
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
433
|
+
ast_node: field_definition,
|
434
|
+
method_conflict_warning: false,
|
435
|
+
camelize: false,
|
436
|
+
directives: prepare_directives(field_definition, type_resolver),
|
437
|
+
resolver_method: resolve_method_name,
|
438
|
+
)
|
439
|
+
|
440
|
+
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
441
|
+
|
442
|
+
# Don't do this for interfaces
|
443
|
+
if default_resolve
|
444
|
+
owner.class_eval <<-RUBY, __FILE__, __LINE__
|
445
|
+
# frozen_string_literal: true
|
446
|
+
def #{resolve_method_name}(**args)
|
447
|
+
field_instance = self.class.get_field("#{field_definition.name}")
|
448
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
449
|
+
end
|
450
|
+
RUBY
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
def build_resolve_type(lookup_hash, directives, missing_type_handler)
|
456
|
+
resolve_type_proc = nil
|
457
|
+
resolve_type_proc = ->(ast_node) {
|
458
|
+
case ast_node
|
459
|
+
when GraphQL::Language::Nodes::TypeName
|
460
|
+
type_name = ast_node.name
|
461
|
+
if lookup_hash.key?(type_name)
|
462
|
+
lookup_hash[type_name]
|
463
|
+
else
|
464
|
+
missing_type_handler.call(type_name)
|
465
|
+
end
|
466
|
+
when GraphQL::Language::Nodes::NonNullType
|
467
|
+
resolve_type_proc.call(ast_node.of_type).to_non_null_type
|
468
|
+
when GraphQL::Language::Nodes::ListType
|
469
|
+
resolve_type_proc.call(ast_node.of_type).to_list_type
|
470
|
+
when String
|
471
|
+
directives[ast_node]
|
472
|
+
else
|
473
|
+
raise "Unexpected ast_node: #{ast_node.inspect}"
|
474
|
+
end
|
475
|
+
}
|
476
|
+
resolve_type_proc
|
477
|
+
end
|
478
|
+
|
479
|
+
def resolve_type_name(type)
|
480
|
+
case type
|
481
|
+
when GraphQL::Language::Nodes::TypeName
|
482
|
+
return type.name
|
483
|
+
else
|
484
|
+
resolve_type_name(type.of_type)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
private_constant :Builder
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
BUILT_IN_TYPES = {
|
5
|
+
"Int" => GraphQL::Types::Int,
|
6
|
+
"String" => GraphQL::Types::String,
|
7
|
+
"Float" => GraphQL::Types::Float,
|
8
|
+
"Boolean" => GraphQL::Types::Boolean,
|
9
|
+
"ID" => GraphQL::Types::ID,
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
class Deprecated < GraphQL::Schema::Directive
|
6
|
+
description "Marks an element of a GraphQL schema as no longer supported."
|
7
|
+
locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE, GraphQL::Schema::Directive::ARGUMENT_DEFINITION, GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION)
|
8
|
+
|
9
|
+
reason_description = "Explains why this element was deprecated, usually also including a "\
|
10
|
+
"suggestion for how to access supported similar data. Formatted "\
|
11
|
+
"in [Markdown](https://daringfireball.net/projects/markdown/)."
|
12
|
+
|
13
|
+
argument :reason, String, reason_description, default_value: Directive::DEFAULT_DEPRECATION_REASON, required: false
|
14
|
+
default_directive true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
# An example directive to show how you might interact with the runtime.
|
6
|
+
#
|
7
|
+
# This directive might be used along with a server-side feature flag system like Flipper.
|
8
|
+
#
|
9
|
+
# With that system, you could use this directive to exclude parts of a query
|
10
|
+
# if the current viewer doesn't have certain flags enabled.
|
11
|
+
# (So, this flag would be for internal clients, like your iOS app, not third-party API clients.)
|
12
|
+
#
|
13
|
+
# To use it, you have to implement `.enabled?`, for example:
|
14
|
+
#
|
15
|
+
# @example Implementing the Feature directive
|
16
|
+
# # app/graphql/directives/feature.rb
|
17
|
+
# class Directives::Feature < GraphQL::Schema::Directive::Feature
|
18
|
+
# def self.enabled?(flag_name, _obj, context)
|
19
|
+
# # Translate some GraphQL data for Ruby:
|
20
|
+
# flag_key = flag_name.underscore
|
21
|
+
# current_user = context[:viewer]
|
22
|
+
# # Check the feature flag however your app does it:
|
23
|
+
# MyFeatureFlags.enabled?(current_user, flag_key)
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# @example Flagging a part of the query
|
28
|
+
# viewer {
|
29
|
+
# # This field only runs if `.enabled?("recommendationEngine", obj, context)`
|
30
|
+
# # returns true. Otherwise, it's treated as if it didn't exist.
|
31
|
+
# recommendations @feature(flag: "recommendationEngine") {
|
32
|
+
# name
|
33
|
+
# rating
|
34
|
+
# }
|
35
|
+
# }
|
36
|
+
class Feature < Schema::Directive
|
37
|
+
description "Directs the executor to run this only if a certain server-side feature is enabled."
|
38
|
+
|
39
|
+
locations(
|
40
|
+
GraphQL::Schema::Directive::FIELD,
|
41
|
+
GraphQL::Schema::Directive::FRAGMENT_SPREAD,
|
42
|
+
GraphQL::Schema::Directive::INLINE_FRAGMENT
|
43
|
+
)
|
44
|
+
|
45
|
+
argument :flag, String,
|
46
|
+
description: "The name of the feature to check before continuing"
|
47
|
+
|
48
|
+
# Implement the Directive API
|
49
|
+
def self.include?(object, arguments, context)
|
50
|
+
flag_name = arguments[:flag]
|
51
|
+
self.enabled?(flag_name, object, context)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Override this method in your app's subclass of this directive.
|
55
|
+
#
|
56
|
+
# @param flag_name [String] The client-provided string of a feature to check
|
57
|
+
# @param object [GraphQL::Schema::Objct] The currently-evaluated GraphQL object instance
|
58
|
+
# @param context [GraphQL::Query::Context]
|
59
|
+
# @return [Boolean] If truthy, execution will continue
|
60
|
+
def self.enabled?(flag_name, object, context)
|
61
|
+
raise GraphQL::RequiredImplementationMissingError, "Implement `.enabled?(flag_name, object, context)` to return true or false for the feature flag (#{flag_name.inspect})"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
# This is _similar_ to {Directive::Feature}, except it's prescribed by the server, not the client.
|
6
|
+
#
|
7
|
+
# In this case, the server hides types and fields _entirely_, unless the current context has certain `:flags` present.
|
8
|
+
class Flagged < GraphQL::Schema::Directive
|
9
|
+
def initialize(target, **options)
|
10
|
+
if target.is_a?(Module) && !target.ancestors.include?(VisibleByFlag)
|
11
|
+
# This is type class of some kind, `include` will put this module
|
12
|
+
# in between the type class itself and its super class, so `super` will work fine
|
13
|
+
target.include(VisibleByFlag)
|
14
|
+
elsif !target.is_a?(VisibleByFlag)
|
15
|
+
# This is an instance of a base class. `include` won't put this in front of the
|
16
|
+
# base class implementation, so we need to `.prepend`.
|
17
|
+
# `#visible?` could probably be moved to a module and then this could use `include` instead.
|
18
|
+
target.class.prepend(VisibleByFlag)
|
19
|
+
end
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
description "Hides this part of the schema unless the named flag is present in context[:flags]"
|
24
|
+
|
25
|
+
locations(
|
26
|
+
GraphQL::Schema::Directive::FIELD_DEFINITION,
|
27
|
+
GraphQL::Schema::Directive::OBJECT,
|
28
|
+
GraphQL::Schema::Directive::SCALAR,
|
29
|
+
GraphQL::Schema::Directive::ENUM,
|
30
|
+
GraphQL::Schema::Directive::UNION,
|
31
|
+
GraphQL::Schema::Directive::INTERFACE,
|
32
|
+
GraphQL::Schema::Directive::INPUT_OBJECT,
|
33
|
+
GraphQL::Schema::Directive::ENUM_VALUE,
|
34
|
+
GraphQL::Schema::Directive::ARGUMENT_DEFINITION,
|
35
|
+
GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION,
|
36
|
+
)
|
37
|
+
|
38
|
+
argument :by, [String], "Flags to check for this schema member"
|
39
|
+
|
40
|
+
module VisibleByFlag
|
41
|
+
def self.included(schema_class)
|
42
|
+
schema_class.extend(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def visible?(context)
|
46
|
+
if dir = self.directives.find { |d| d.is_a?(Flagged) }
|
47
|
+
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
48
|
+
relevant_flags && relevant_flags.any? && super
|
49
|
+
else
|
50
|
+
super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
class Include < GraphQL::Schema::Directive
|
6
|
+
description "Directs the executor to include this field or fragment only when the `if` argument is true."
|
7
|
+
|
8
|
+
locations(
|
9
|
+
GraphQL::Schema::Directive::FIELD,
|
10
|
+
GraphQL::Schema::Directive::FRAGMENT_SPREAD,
|
11
|
+
GraphQL::Schema::Directive::INLINE_FRAGMENT
|
12
|
+
)
|
13
|
+
|
14
|
+
argument :if, Boolean,
|
15
|
+
description: "Included when true."
|
16
|
+
|
17
|
+
default_directive true
|
18
|
+
|
19
|
+
def self.static_include?(args, ctx)
|
20
|
+
!!args[:if]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
class OneOf < GraphQL::Schema::Directive
|
6
|
+
description "Requires that exactly one field must be supplied and that field must not be `null`."
|
7
|
+
locations(GraphQL::Schema::Directive::INPUT_OBJECT)
|
8
|
+
default_directive true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|