graphql_cody 1.13.0
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 +7 -0
- data/.yardopts +5 -0
- data/MIT-LICENSE +20 -0
- data/lib/generators/graphql/core.rb +74 -0
- data/lib/generators/graphql/enum_generator.rb +33 -0
- data/lib/generators/graphql/install_generator.rb +190 -0
- data/lib/generators/graphql/interface_generator.rb +27 -0
- data/lib/generators/graphql/loader_generator.rb +21 -0
- data/lib/generators/graphql/mutation_generator.rb +55 -0
- data/lib/generators/graphql/object_generator.rb +79 -0
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +20 -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_mutation.erb +10 -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 +7 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +52 -0
- data/lib/generators/graphql/templates/interface.erb +8 -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_type.erb +12 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +8 -0
- data/lib/generators/graphql/templates/query_type.erb +15 -0
- data/lib/generators/graphql/templates/scalar.erb +15 -0
- data/lib/generators/graphql/templates/schema.erb +27 -0
- data/lib/generators/graphql/templates/union.erb +7 -0
- data/lib/generators/graphql/type_generator.rb +98 -0
- data/lib/generators/graphql/union_generator.rb +33 -0
- data/lib/graphql/analysis/analyze_query.rb +98 -0
- data/lib/graphql/analysis/ast/analyzer.rb +84 -0
- data/lib/graphql/analysis/ast/field_usage.rb +51 -0
- data/lib/graphql/analysis/ast/max_query_complexity.rb +23 -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 +56 -0
- data/lib/graphql/analysis/ast/visitor.rb +268 -0
- data/lib/graphql/analysis/ast.rb +91 -0
- data/lib/graphql/analysis/field_usage.rb +45 -0
- data/lib/graphql/analysis/max_query_complexity.rb +26 -0
- data/lib/graphql/analysis/max_query_depth.rb +26 -0
- data/lib/graphql/analysis/query_complexity.rb +88 -0
- data/lib/graphql/analysis/query_depth.rb +43 -0
- data/lib/graphql/analysis/reducer_state.rb +48 -0
- data/lib/graphql/analysis.rb +9 -0
- data/lib/graphql/analysis_error.rb +5 -0
- data/lib/graphql/argument.rb +131 -0
- data/lib/graphql/authorization.rb +82 -0
- data/lib/graphql/backtrace/inspect_result.rb +50 -0
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +159 -0
- data/lib/graphql/backtrace/traced_error.rb +54 -0
- data/lib/graphql/backtrace/tracer.rb +81 -0
- data/lib/graphql/backtrace.rb +64 -0
- data/lib/graphql/backwards_compatibility.rb +61 -0
- data/lib/graphql/base_type.rb +230 -0
- data/lib/graphql/boolean_type.rb +2 -0
- data/lib/graphql/coercion_error.rb +13 -0
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +53 -0
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +200 -0
- data/lib/graphql/compatibility/execution_specification.rb +436 -0
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +111 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +215 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +87 -0
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +79 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +266 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +682 -0
- data/lib/graphql/compatibility.rb +5 -0
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/define/assign_argument.rb +12 -0
- data/lib/graphql/define/assign_connection.rb +13 -0
- data/lib/graphql/define/assign_enum_value.rb +18 -0
- data/lib/graphql/define/assign_global_id_field.rb +11 -0
- data/lib/graphql/define/assign_mutation_function.rb +34 -0
- data/lib/graphql/define/assign_object_field.rb +42 -0
- data/lib/graphql/define/defined_object_proxy.rb +53 -0
- data/lib/graphql/define/instance_definable.rb +240 -0
- data/lib/graphql/define/no_definition_error.rb +7 -0
- data/lib/graphql/define/non_null_with_bang.rb +16 -0
- data/lib/graphql/define/type_definer.rb +31 -0
- data/lib/graphql/define.rb +31 -0
- data/lib/graphql/deprecated_dsl.rb +55 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +19 -0
- data/lib/graphql/directive/deprecated_directive.rb +2 -0
- data/lib/graphql/directive/include_directive.rb +2 -0
- data/lib/graphql/directive/skip_directive.rb +2 -0
- data/lib/graphql/directive.rb +107 -0
- data/lib/graphql/enum_type.rb +133 -0
- data/lib/graphql/execution/directive_checks.rb +37 -0
- data/lib/graphql/execution/errors.rb +163 -0
- data/lib/graphql/execution/execute.rb +333 -0
- data/lib/graphql/execution/flatten.rb +40 -0
- data/lib/graphql/execution/instrumentation.rb +92 -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 +103 -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 +70 -0
- data/lib/graphql/execution/interpreter/runtime.rb +949 -0
- data/lib/graphql/execution/interpreter.rb +122 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +98 -0
- data/lib/graphql/execution/lazy/resolve.rb +91 -0
- data/lib/graphql/execution/lazy.rb +83 -0
- data/lib/graphql/execution/lookahead.rb +307 -0
- data/lib/graphql/execution/multiplex.rb +214 -0
- data/lib/graphql/execution/typecast.rb +50 -0
- data/lib/graphql/execution.rb +11 -0
- data/lib/graphql/execution_error.rb +58 -0
- data/lib/graphql/field/resolve.rb +59 -0
- data/lib/graphql/field.rb +226 -0
- data/lib/graphql/filter.rb +53 -0
- data/lib/graphql/float_type.rb +2 -0
- data/lib/graphql/function.rb +128 -0
- data/lib/graphql/id_type.rb +2 -0
- data/lib/graphql/input_object_type.rb +138 -0
- data/lib/graphql/int_type.rb +2 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +36 -0
- data/lib/graphql/interface_type.rb +72 -0
- data/lib/graphql/internal_representation/document.rb +27 -0
- data/lib/graphql/internal_representation/node.rb +206 -0
- data/lib/graphql/internal_representation/print.rb +51 -0
- data/lib/graphql/internal_representation/rewrite.rb +184 -0
- data/lib/graphql/internal_representation/scope.rb +88 -0
- data/lib/graphql/internal_representation/visit.rb +36 -0
- data/lib/graphql/internal_representation.rb +7 -0
- data/lib/graphql/introspection/base_object.rb +13 -0
- data/lib/graphql/introspection/directive_location_enum.rb +15 -0
- data/lib/graphql/introspection/directive_type.rb +29 -0
- data/lib/graphql/introspection/dynamic_fields.rb +17 -0
- data/lib/graphql/introspection/entry_points.rb +35 -0
- data/lib/graphql/introspection/enum_value_type.rb +23 -0
- data/lib/graphql/introspection/field_type.rb +28 -0
- data/lib/graphql/introspection/input_value_type.rb +67 -0
- data/lib/graphql/introspection/introspection_query.rb +7 -0
- data/lib/graphql/introspection/schema_type.rb +44 -0
- data/lib/graphql/introspection/type_kind_enum.rb +13 -0
- data/lib/graphql/introspection/type_type.rb +95 -0
- data/lib/graphql/introspection.rb +114 -0
- data/lib/graphql/invalid_name_error.rb +11 -0
- data/lib/graphql/invalid_null_error.rb +50 -0
- 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 +347 -0
- data/lib/graphql/language/generation.rb +24 -0
- data/lib/graphql/language/lexer.rb +1467 -0
- data/lib/graphql/language/lexer.rl +258 -0
- data/lib/graphql/language/nodes.rb +707 -0
- data/lib/graphql/language/parser.rb +1974 -0
- data/lib/graphql/language/parser.y +544 -0
- data/lib/graphql/language/printer.rb +366 -0
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +34 -0
- data/lib/graphql/language/visitor.rb +242 -0
- data/lib/graphql/language.rb +36 -0
- data/lib/graphql/list_type.rb +80 -0
- data/lib/graphql/load_application_object_failed_error.rb +22 -0
- data/lib/graphql/name_validator.rb +11 -0
- data/lib/graphql/non_null_type.rb +71 -0
- data/lib/graphql/object_type.rb +130 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +48 -0
- data/lib/graphql/pagination/array_connection.rb +77 -0
- data/lib/graphql/pagination/connection.rb +226 -0
- data/lib/graphql/pagination/connections.rb +160 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +196 -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/arguments.rb +189 -0
- data/lib/graphql/query/arguments_cache.rb +24 -0
- data/lib/graphql/query/context.rb +371 -0
- data/lib/graphql/query/executor.rb +52 -0
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +43 -0
- data/lib/graphql/query/literal_input.rb +136 -0
- data/lib/graphql/query/null_context.rb +55 -0
- data/lib/graphql/query/result.rb +63 -0
- data/lib/graphql/query/serial_execution/field_resolution.rb +92 -0
- data/lib/graphql/query/serial_execution/operation_resolution.rb +19 -0
- data/lib/graphql/query/serial_execution/selection_resolution.rb +23 -0
- data/lib/graphql/query/serial_execution/value_resolution.rb +87 -0
- data/lib/graphql/query/serial_execution.rb +40 -0
- data/lib/graphql/query/validation_pipeline.rb +139 -0
- data/lib/graphql/query/variable_validation_error.rb +44 -0
- data/lib/graphql/query/variables.rb +78 -0
- data/lib/graphql/query.rb +454 -0
- data/lib/graphql/railtie.rb +117 -0
- data/lib/graphql/rake_task/validate.rb +63 -0
- data/lib/graphql/rake_task.rb +145 -0
- data/lib/graphql/relay/array_connection.rb +83 -0
- data/lib/graphql/relay/base_connection.rb +189 -0
- data/lib/graphql/relay/connection_instrumentation.rb +54 -0
- data/lib/graphql/relay/connection_resolve.rb +43 -0
- data/lib/graphql/relay/connection_type.rb +41 -0
- data/lib/graphql/relay/edge.rb +27 -0
- data/lib/graphql/relay/edge_type.rb +19 -0
- data/lib/graphql/relay/edges_instrumentation.rb +39 -0
- data/lib/graphql/relay/global_id_resolve.rb +18 -0
- data/lib/graphql/relay/mongo_relation_connection.rb +50 -0
- data/lib/graphql/relay/mutation/instrumentation.rb +23 -0
- data/lib/graphql/relay/mutation/resolve.rb +56 -0
- data/lib/graphql/relay/mutation/result.rb +38 -0
- data/lib/graphql/relay/mutation.rb +106 -0
- data/lib/graphql/relay/node.rb +39 -0
- data/lib/graphql/relay/page_info.rb +7 -0
- data/lib/graphql/relay/range_add.rb +59 -0
- data/lib/graphql/relay/relation_connection.rb +188 -0
- data/lib/graphql/relay/type_extensions.rb +32 -0
- data/lib/graphql/relay.rb +18 -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/scalar_type.rb +91 -0
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +383 -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 +477 -0
- data/lib/graphql/schema/built_in_types.rb +12 -0
- data/lib/graphql/schema/catchall_middleware.rb +35 -0
- data/lib/graphql/schema/default_parse_error.rb +10 -0
- data/lib/graphql/schema/default_type_error.rb +17 -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/skip.rb +25 -0
- data/lib/graphql/schema/directive/transform.rb +60 -0
- data/lib/graphql/schema/directive.rb +210 -0
- data/lib/graphql/schema/enum.rb +193 -0
- data/lib/graphql/schema/enum_value.rb +97 -0
- data/lib/graphql/schema/field/connection_extension.rb +76 -0
- data/lib/graphql/schema/field/scope_extension.rb +22 -0
- data/lib/graphql/schema/field.rb +880 -0
- data/lib/graphql/schema/field_extension.rb +69 -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 +253 -0
- data/lib/graphql/schema/interface.rb +136 -0
- data/lib/graphql/schema/introspection_system.rb +169 -0
- data/lib/graphql/schema/invalid_type_error.rb +7 -0
- data/lib/graphql/schema/late_bound_type.rb +33 -0
- data/lib/graphql/schema/list.rb +75 -0
- data/lib/graphql/schema/loader.rb +226 -0
- data/lib/graphql/schema/member/accepts_definition.rb +159 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +129 -0
- data/lib/graphql/schema/member/build_type.rb +180 -0
- data/lib/graphql/schema/member/cached_graphql_definition.rb +31 -0
- data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
- data/lib/graphql/schema/member/has_arguments.rb +332 -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 +98 -0
- data/lib/graphql/schema/member/has_fields.rb +163 -0
- data/lib/graphql/schema/member/has_interfaces.rb +90 -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/instrumentation.rb +131 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -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 +161 -0
- data/lib/graphql/schema/middleware_chain.rb +82 -0
- data/lib/graphql/schema/mutation.rb +94 -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 +150 -0
- data/lib/graphql/schema/possible_types.rb +44 -0
- data/lib/graphql/schema/printer.rb +100 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +160 -0
- data/lib/graphql/schema/rescue_middleware.rb +60 -0
- data/lib/graphql/schema/resolver/has_payload_type.rb +96 -0
- data/lib/graphql/schema/resolver.rb +397 -0
- data/lib/graphql/schema/scalar.rb +69 -0
- data/lib/graphql/schema/subscription.rb +155 -0
- data/lib/graphql/schema/timeout.rb +123 -0
- data/lib/graphql/schema/timeout_middleware.rb +88 -0
- data/lib/graphql/schema/traversal.rb +228 -0
- data/lib/graphql/schema/type_expression.rb +43 -0
- data/lib/graphql/schema/type_membership.rb +48 -0
- data/lib/graphql/schema/union.rb +95 -0
- data/lib/graphql/schema/unique_within_type.rb +34 -0
- data/lib/graphql/schema/validation.rb +313 -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 +68 -0
- data/lib/graphql/schema/validator.rb +174 -0
- data/lib/graphql/schema/warden.rb +409 -0
- data/lib/graphql/schema/wrapper.rb +29 -0
- data/lib/graphql/schema.rb +1945 -0
- data/lib/graphql/static_validation/all_rules.rb +40 -0
- data/lib/graphql/static_validation/base_visitor.rb +217 -0
- data/lib/graphql/static_validation/default_visitor.rb +15 -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 +139 -0
- data/lib/graphql/static_validation/no_validate_visitor.rb +10 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +66 -0
- 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 +71 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +37 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +23 -0
- 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 +65 -0
- 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 +30 -0
- 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 +73 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +418 -0
- 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 +73 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +39 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +21 -0
- 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 +37 -0
- 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 +32 -0
- 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/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/required_arguments_are_present.rb +37 -0
- 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 +50 -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 +46 -0
- 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 +153 -0
- 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 +39 -0
- 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 +155 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
- data/lib/graphql/static_validation/type_stack.rb +216 -0
- data/lib/graphql/static_validation/validation_context.rb +49 -0
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +96 -0
- data/lib/graphql/static_validation.rb +19 -0
- data/lib/graphql/string_encoding_error.rb +20 -0
- data/lib/graphql/string_type.rb +2 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +245 -0
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +144 -0
- data/lib/graphql/subscriptions/instrumentation.rb +79 -0
- data/lib/graphql/subscriptions/serialize.rb +138 -0
- data/lib/graphql/subscriptions/subscription_root.rb +76 -0
- data/lib/graphql/subscriptions.rb +299 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +35 -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 +76 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +51 -0
- data/lib/graphql/tracing/platform_tracing.rb +139 -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/skylight_tracing.rb +70 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +95 -0
- data/lib/graphql/type_kinds.rb +77 -0
- 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 +34 -0
- data/lib/graphql/types/iso_8601_date_time.rb +65 -0
- data/lib/graphql/types/json.rb +25 -0
- data/lib/graphql/types/relay/base_connection.rb +39 -0
- data/lib/graphql/types/relay/base_edge.rb +29 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +53 -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 +15 -0
- data/lib/graphql/types/relay/node_field.rb +25 -0
- data/lib/graphql/types/relay/nodes_field.rb +27 -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 +41 -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/union_type.rb +115 -0
- data/lib/graphql/unresolved_type_error.rb +35 -0
- data/lib/graphql/upgrader/member.rb +937 -0
- data/lib/graphql/upgrader/schema.rb +38 -0
- data/lib/graphql/version.rb +4 -0
- data/lib/graphql.rb +168 -0
- data/readme.md +49 -0
- metadata +714 -0
@@ -0,0 +1,477 @@
|
|
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(definition_string, parser: GraphQL.default_parser, **kwargs)
|
10
|
+
from_document(parser.parse(definition_string), **kwargs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
|
14
|
+
from_document(parser.parse_file(definition_path), **kwargs)
|
15
|
+
end
|
16
|
+
|
17
|
+
def from_document(document, default_resolve:, using: {}, relay: false)
|
18
|
+
Builder.build(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(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 = {}
|
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
|
+
document.definitions.each do |definition|
|
59
|
+
if definition.is_a?(GraphQL::Language::Nodes::DirectiveDefinition)
|
60
|
+
directives[definition.name] = build_directive(definition, directive_type_resolver)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
directives = GraphQL::Schema.default_directives.merge(directives)
|
65
|
+
|
66
|
+
# In case any directives referenced built-in types for their arguments:
|
67
|
+
replace_late_bound_types_with_built_in(types)
|
68
|
+
|
69
|
+
document.definitions.each do |definition|
|
70
|
+
case definition
|
71
|
+
when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
|
72
|
+
nil # already handled
|
73
|
+
else
|
74
|
+
# It's possible that this was already loaded by the directives
|
75
|
+
prev_type = types[definition.name]
|
76
|
+
if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
|
77
|
+
types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
replace_late_bound_types_with_built_in(types)
|
83
|
+
|
84
|
+
if schema_definition
|
85
|
+
if schema_definition.query
|
86
|
+
raise InvalidDocumentError.new("Specified query type \"#{schema_definition.query}\" not found in document.") unless types[schema_definition.query]
|
87
|
+
query_root_type = types[schema_definition.query]
|
88
|
+
end
|
89
|
+
|
90
|
+
if schema_definition.mutation
|
91
|
+
raise InvalidDocumentError.new("Specified mutation type \"#{schema_definition.mutation}\" not found in document.") unless types[schema_definition.mutation]
|
92
|
+
mutation_root_type = types[schema_definition.mutation]
|
93
|
+
end
|
94
|
+
|
95
|
+
if schema_definition.subscription
|
96
|
+
raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
|
97
|
+
subscription_root_type = types[schema_definition.subscription]
|
98
|
+
end
|
99
|
+
else
|
100
|
+
query_root_type = types['Query']
|
101
|
+
mutation_root_type = types['Mutation']
|
102
|
+
subscription_root_type = types['Subscription']
|
103
|
+
end
|
104
|
+
|
105
|
+
raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
|
106
|
+
|
107
|
+
Class.new(GraphQL::Schema) do
|
108
|
+
begin
|
109
|
+
# Add these first so that there's some chance of resolving late-bound types
|
110
|
+
orphan_types types.values
|
111
|
+
query query_root_type
|
112
|
+
mutation mutation_root_type
|
113
|
+
subscription subscription_root_type
|
114
|
+
rescue Schema::UnresolvedLateBoundTypeError => err
|
115
|
+
type_name = err.type.name
|
116
|
+
err_backtrace = err.backtrace
|
117
|
+
raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
|
118
|
+
end
|
119
|
+
|
120
|
+
if default_resolve.respond_to?(:resolve_type)
|
121
|
+
def self.resolve_type(*args)
|
122
|
+
self.definition_default_resolve.resolve_type(*args)
|
123
|
+
end
|
124
|
+
else
|
125
|
+
def self.resolve_type(*args)
|
126
|
+
NullResolveType.call(*args)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
directives directives.values
|
131
|
+
|
132
|
+
if schema_definition
|
133
|
+
ast_node(schema_definition)
|
134
|
+
end
|
135
|
+
|
136
|
+
using.each do |plugin, options|
|
137
|
+
if options
|
138
|
+
use(plugin, **options)
|
139
|
+
else
|
140
|
+
use(plugin)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Empty `orphan_types` -- this will make unreachable types ... unreachable.
|
145
|
+
own_orphan_types.clear
|
146
|
+
|
147
|
+
class << self
|
148
|
+
attr_accessor :definition_default_resolve
|
149
|
+
end
|
150
|
+
|
151
|
+
self.definition_default_resolve = default_resolve
|
152
|
+
|
153
|
+
def definition_default_resolve
|
154
|
+
self.class.definition_default_resolve
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.inherited(child_class)
|
158
|
+
child_class.definition_default_resolve = self.definition_default_resolve
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
NullResolveType = ->(type, obj, ctx) {
|
164
|
+
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
|
165
|
+
}
|
166
|
+
|
167
|
+
def build_definition_from_node(definition, type_resolver, default_resolve)
|
168
|
+
case definition
|
169
|
+
when GraphQL::Language::Nodes::EnumTypeDefinition
|
170
|
+
build_enum_type(definition, type_resolver)
|
171
|
+
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
172
|
+
build_object_type(definition, type_resolver)
|
173
|
+
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
174
|
+
build_interface_type(definition, type_resolver)
|
175
|
+
when GraphQL::Language::Nodes::UnionTypeDefinition
|
176
|
+
build_union_type(definition, type_resolver)
|
177
|
+
when GraphQL::Language::Nodes::ScalarTypeDefinition
|
178
|
+
build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
|
179
|
+
when GraphQL::Language::Nodes::InputObjectTypeDefinition
|
180
|
+
build_input_object_type(definition, type_resolver)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Modify `types`, replacing any late-bound references to built-in types
|
185
|
+
# with their actual definitions.
|
186
|
+
#
|
187
|
+
# (Schema definitions are allowed to reference those built-ins without redefining them.)
|
188
|
+
# @return void
|
189
|
+
def replace_late_bound_types_with_built_in(types)
|
190
|
+
GraphQL::Schema::BUILT_IN_TYPES.each do |scalar_name, built_in_scalar|
|
191
|
+
existing_type = types[scalar_name]
|
192
|
+
if existing_type.is_a?(GraphQL::Schema::LateBoundType)
|
193
|
+
types[scalar_name] = built_in_scalar
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def build_directives(definition, ast_node, type_resolver)
|
199
|
+
dirs = prepare_directives(ast_node, type_resolver)
|
200
|
+
dirs.each do |dir_class, options|
|
201
|
+
definition.directive(dir_class, **options)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def prepare_directives(ast_node, type_resolver)
|
206
|
+
dirs = {}
|
207
|
+
ast_node.directives.each do |dir_node|
|
208
|
+
if dir_node.name == "deprecated"
|
209
|
+
# This is handled using `deprecation_reason`
|
210
|
+
next
|
211
|
+
else
|
212
|
+
dir_class = type_resolver.call(dir_node.name)
|
213
|
+
if dir_class.nil?
|
214
|
+
raise ArgumentError, "No definition for @#{dir_node.name} on #{ast_node.name} at #{ast_node.line}:#{ast_node.col}"
|
215
|
+
end
|
216
|
+
options = args_to_kwargs(dir_class, dir_node)
|
217
|
+
dirs[dir_class] = options
|
218
|
+
end
|
219
|
+
end
|
220
|
+
dirs
|
221
|
+
end
|
222
|
+
|
223
|
+
def args_to_kwargs(arg_owner, node)
|
224
|
+
if node.respond_to?(:arguments)
|
225
|
+
kwargs = {}
|
226
|
+
node.arguments.each do |arg_node|
|
227
|
+
arg_defn = arg_owner.get_argument(arg_node.name)
|
228
|
+
kwargs[arg_defn.keyword] = args_to_kwargs(arg_defn.type.unwrap, arg_node.value)
|
229
|
+
end
|
230
|
+
kwargs
|
231
|
+
elsif node.is_a?(Array)
|
232
|
+
node.map { |n| args_to_kwargs(arg_owner, n) }
|
233
|
+
elsif node.is_a?(Language::Nodes::Enum)
|
234
|
+
node.name
|
235
|
+
else
|
236
|
+
# scalar
|
237
|
+
node
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def build_enum_type(enum_type_definition, type_resolver)
|
242
|
+
builder = self
|
243
|
+
Class.new(GraphQL::Schema::Enum) do
|
244
|
+
graphql_name(enum_type_definition.name)
|
245
|
+
builder.build_directives(self, enum_type_definition, type_resolver)
|
246
|
+
description(enum_type_definition.description)
|
247
|
+
ast_node(enum_type_definition)
|
248
|
+
enum_type_definition.values.each do |enum_value_definition|
|
249
|
+
value(enum_value_definition.name,
|
250
|
+
value: enum_value_definition.name,
|
251
|
+
deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
|
252
|
+
description: enum_value_definition.description,
|
253
|
+
directives: builder.prepare_directives(enum_value_definition, type_resolver),
|
254
|
+
ast_node: enum_value_definition,
|
255
|
+
)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def build_deprecation_reason(directives)
|
261
|
+
deprecated_directive = directives.find{ |d| d.name == 'deprecated' }
|
262
|
+
return unless deprecated_directive
|
263
|
+
|
264
|
+
reason = deprecated_directive.arguments.find{ |a| a.name == 'reason' }
|
265
|
+
return GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON unless reason
|
266
|
+
|
267
|
+
reason.value
|
268
|
+
end
|
269
|
+
|
270
|
+
def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
|
271
|
+
builder = self
|
272
|
+
Class.new(GraphQL::Schema::Scalar) do
|
273
|
+
graphql_name(scalar_type_definition.name)
|
274
|
+
description(scalar_type_definition.description)
|
275
|
+
ast_node(scalar_type_definition)
|
276
|
+
builder.build_directives(self, scalar_type_definition, type_resolver)
|
277
|
+
|
278
|
+
if default_resolve.respond_to?(:coerce_input)
|
279
|
+
# Put these method definitions in another method to avoid retaining `type_resolve`
|
280
|
+
# from this method's bindiing
|
281
|
+
builder.build_scalar_type_coerce_method(self, :coerce_input, default_resolve)
|
282
|
+
builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
|
288
|
+
scalar_class.define_singleton_method(method_name) do |val, ctx|
|
289
|
+
default_definition_resolve.public_send(method_name, self, val, ctx)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
def build_union_type(union_type_definition, type_resolver)
|
294
|
+
builder = self
|
295
|
+
Class.new(GraphQL::Schema::Union) do
|
296
|
+
graphql_name(union_type_definition.name)
|
297
|
+
description(union_type_definition.description)
|
298
|
+
possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
|
299
|
+
ast_node(union_type_definition)
|
300
|
+
builder.build_directives(self, union_type_definition, type_resolver)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def build_object_type(object_type_definition, type_resolver)
|
305
|
+
builder = self
|
306
|
+
|
307
|
+
Class.new(GraphQL::Schema::Object) do
|
308
|
+
graphql_name(object_type_definition.name)
|
309
|
+
description(object_type_definition.description)
|
310
|
+
ast_node(object_type_definition)
|
311
|
+
builder.build_directives(self, object_type_definition, type_resolver)
|
312
|
+
|
313
|
+
object_type_definition.interfaces.each do |interface_name|
|
314
|
+
interface_defn = type_resolver.call(interface_name)
|
315
|
+
implements(interface_defn)
|
316
|
+
end
|
317
|
+
|
318
|
+
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def build_input_object_type(input_object_type_definition, type_resolver)
|
323
|
+
builder = self
|
324
|
+
Class.new(GraphQL::Schema::InputObject) do
|
325
|
+
graphql_name(input_object_type_definition.name)
|
326
|
+
description(input_object_type_definition.description)
|
327
|
+
ast_node(input_object_type_definition)
|
328
|
+
builder.build_directives(self, input_object_type_definition, type_resolver)
|
329
|
+
builder.build_arguments(self, input_object_type_definition.fields, type_resolver)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def build_default_value(default_value)
|
334
|
+
case default_value
|
335
|
+
when GraphQL::Language::Nodes::Enum
|
336
|
+
default_value.name
|
337
|
+
when GraphQL::Language::Nodes::NullValue
|
338
|
+
nil
|
339
|
+
when GraphQL::Language::Nodes::InputObject
|
340
|
+
default_value.to_h
|
341
|
+
when Array
|
342
|
+
default_value.map { |v| build_default_value(v) }
|
343
|
+
else
|
344
|
+
default_value
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
NO_DEFAULT_VALUE = {}.freeze
|
349
|
+
|
350
|
+
def build_arguments(type_class, arguments, type_resolver)
|
351
|
+
builder = self
|
352
|
+
|
353
|
+
arguments.each do |argument_defn|
|
354
|
+
default_value_kwargs = if !argument_defn.default_value.nil?
|
355
|
+
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
356
|
+
else
|
357
|
+
NO_DEFAULT_VALUE
|
358
|
+
end
|
359
|
+
|
360
|
+
type_class.argument(
|
361
|
+
argument_defn.name,
|
362
|
+
type: type_resolver.call(argument_defn.type),
|
363
|
+
required: false,
|
364
|
+
description: argument_defn.description,
|
365
|
+
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
366
|
+
ast_node: argument_defn,
|
367
|
+
camelize: false,
|
368
|
+
method_access: false,
|
369
|
+
directives: prepare_directives(argument_defn, type_resolver),
|
370
|
+
**default_value_kwargs
|
371
|
+
)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def build_directive(directive_definition, type_resolver)
|
376
|
+
builder = self
|
377
|
+
Class.new(GraphQL::Schema::Directive) do
|
378
|
+
graphql_name(directive_definition.name)
|
379
|
+
description(directive_definition.description)
|
380
|
+
locations(*directive_definition.locations.map { |location| location.name.to_sym })
|
381
|
+
ast_node(directive_definition)
|
382
|
+
builder.build_arguments(self, directive_definition.arguments, type_resolver)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def build_interface_type(interface_type_definition, type_resolver)
|
387
|
+
builder = self
|
388
|
+
Module.new do
|
389
|
+
include GraphQL::Schema::Interface
|
390
|
+
graphql_name(interface_type_definition.name)
|
391
|
+
description(interface_type_definition.description)
|
392
|
+
interface_type_definition.interfaces.each do |interface_name|
|
393
|
+
"Implements: #{interface_type_definition} -> #{interface_name}"
|
394
|
+
interface_defn = type_resolver.call(interface_name)
|
395
|
+
implements(interface_defn)
|
396
|
+
end
|
397
|
+
ast_node(interface_type_definition)
|
398
|
+
builder.build_directives(self, interface_type_definition, type_resolver)
|
399
|
+
|
400
|
+
builder.build_fields(self, interface_type_definition.fields, type_resolver, default_resolve: nil)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
|
405
|
+
builder = self
|
406
|
+
|
407
|
+
field_definitions.each do |field_definition|
|
408
|
+
type_name = resolve_type_name(field_definition.type)
|
409
|
+
resolve_method_name = -"resolve_field_#{field_definition.name}"
|
410
|
+
schema_field_defn = owner.field(
|
411
|
+
field_definition.name,
|
412
|
+
description: field_definition.description,
|
413
|
+
type: type_resolver.call(field_definition.type),
|
414
|
+
null: true,
|
415
|
+
connection: type_name.end_with?("Connection"),
|
416
|
+
connection_extension: nil,
|
417
|
+
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
418
|
+
ast_node: field_definition,
|
419
|
+
method_conflict_warning: false,
|
420
|
+
camelize: false,
|
421
|
+
directives: prepare_directives(field_definition, type_resolver),
|
422
|
+
resolver_method: resolve_method_name,
|
423
|
+
)
|
424
|
+
|
425
|
+
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
426
|
+
|
427
|
+
# Don't do this for interfaces
|
428
|
+
if default_resolve
|
429
|
+
owner.class_eval <<-RUBY, __FILE__, __LINE__
|
430
|
+
# frozen_string_literal: true
|
431
|
+
def #{resolve_method_name}(**args)
|
432
|
+
field_instance = self.class.get_field("#{field_definition.name}")
|
433
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
434
|
+
end
|
435
|
+
RUBY
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
def build_resolve_type(lookup_hash, directives, missing_type_handler)
|
441
|
+
resolve_type_proc = nil
|
442
|
+
resolve_type_proc = ->(ast_node) {
|
443
|
+
case ast_node
|
444
|
+
when GraphQL::Language::Nodes::TypeName
|
445
|
+
type_name = ast_node.name
|
446
|
+
if lookup_hash.key?(type_name)
|
447
|
+
lookup_hash[type_name]
|
448
|
+
else
|
449
|
+
missing_type_handler.call(type_name)
|
450
|
+
end
|
451
|
+
when GraphQL::Language::Nodes::NonNullType
|
452
|
+
resolve_type_proc.call(ast_node.of_type).to_non_null_type
|
453
|
+
when GraphQL::Language::Nodes::ListType
|
454
|
+
resolve_type_proc.call(ast_node.of_type).to_list_type
|
455
|
+
when String
|
456
|
+
directives[ast_node]
|
457
|
+
else
|
458
|
+
raise "Unexpected ast_node: #{ast_node.inspect}"
|
459
|
+
end
|
460
|
+
}
|
461
|
+
resolve_type_proc
|
462
|
+
end
|
463
|
+
|
464
|
+
def resolve_type_name(type)
|
465
|
+
case type
|
466
|
+
when GraphQL::Language::Nodes::TypeName
|
467
|
+
return type.name
|
468
|
+
else
|
469
|
+
resolve_type_name(type.of_type)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
private_constant :Builder
|
475
|
+
end
|
476
|
+
end
|
477
|
+
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,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
# In early GraphQL versions, errors would be "automatically"
|
5
|
+
# rescued and replaced with `"Internal error"`. That behavior
|
6
|
+
# was undesirable but this middleware is offered for people who
|
7
|
+
# want to preserve it.
|
8
|
+
#
|
9
|
+
# It has a couple of differences from the previous behavior:
|
10
|
+
#
|
11
|
+
# - Other parts of the query _will_ be run (previously,
|
12
|
+
# execution would stop when the error was raised and the result
|
13
|
+
# would have no `"data"` key at all)
|
14
|
+
# - The entry in {Query::Context#errors} is a {GraphQL::ExecutionError}, _not_
|
15
|
+
# the originally-raised error.
|
16
|
+
# - The entry in the `"errors"` key includes the location of the field
|
17
|
+
# which raised the errors.
|
18
|
+
#
|
19
|
+
# @example Use CatchallMiddleware with your schema
|
20
|
+
# # All errors will be suppressed and replaced with "Internal error" messages
|
21
|
+
# MySchema.middleware << GraphQL::Schema::CatchallMiddleware
|
22
|
+
#
|
23
|
+
module CatchallMiddleware
|
24
|
+
MESSAGE = "Internal error"
|
25
|
+
|
26
|
+
# Rescue any error and replace it with a {GraphQL::ExecutionError}
|
27
|
+
# whose message is {MESSAGE}
|
28
|
+
def self.call(parent_type, parent_object, field_definition, field_args, query_context)
|
29
|
+
yield
|
30
|
+
rescue StandardError
|
31
|
+
GraphQL::ExecutionError.new(MESSAGE)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
module DefaultTypeError
|
5
|
+
def self.call(type_error, ctx)
|
6
|
+
case type_error
|
7
|
+
when GraphQL::InvalidNullError
|
8
|
+
ctx.errors << type_error
|
9
|
+
when GraphQL::UnresolvedTypeError, GraphQL::StringEncodingError, GraphQL::IntegerEncodingError
|
10
|
+
raise type_error
|
11
|
+
when GraphQL::IntegerDecodingError
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
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
|