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,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
# Extend this class to make field-level customizations to resolve behavior.
|
5
|
+
#
|
6
|
+
# When a extension is added to a field with `extension(MyExtension)`, a `MyExtension` instance
|
7
|
+
# is created, and its hooks are applied whenever that field is called.
|
8
|
+
#
|
9
|
+
# The instance is frozen so that instance variables aren't modified during query execution,
|
10
|
+
# which could cause all kinds of issues due to race conditions.
|
11
|
+
class FieldExtension
|
12
|
+
# @return [GraphQL::Schema::Field]
|
13
|
+
attr_reader :field
|
14
|
+
|
15
|
+
# @return [Object]
|
16
|
+
attr_reader :options
|
17
|
+
|
18
|
+
# Called when the extension is mounted with `extension(name, options)`.
|
19
|
+
# The instance is frozen to avoid improper use of state during execution.
|
20
|
+
# @param field [GraphQL::Schema::Field] The field where this extension was mounted
|
21
|
+
# @param options [Object] The second argument to `extension`, or `{}` if nothing was passed.
|
22
|
+
def initialize(field:, options:)
|
23
|
+
@field = field
|
24
|
+
@options = options || {}
|
25
|
+
apply
|
26
|
+
freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
# Called when this extension is attached to a field.
|
30
|
+
# The field definition may be extended during this method.
|
31
|
+
# @return [void]
|
32
|
+
def apply
|
33
|
+
end
|
34
|
+
|
35
|
+
# Called before resolving {#field}. It should either:
|
36
|
+
#
|
37
|
+
# - `yield` values to continue execution; OR
|
38
|
+
# - return something else to shortcut field execution.
|
39
|
+
#
|
40
|
+
# Whatever this method returns will be used for execution.
|
41
|
+
#
|
42
|
+
# @param object [Object] The object the field is being resolved on
|
43
|
+
# @param arguments [Hash] Ruby keyword arguments for resolving this field
|
44
|
+
# @param context [Query::Context] the context for this query
|
45
|
+
# @yieldparam object [Object] The object to continue resolving the field on
|
46
|
+
# @yieldparam arguments [Hash] The keyword arguments to continue resolving with
|
47
|
+
# @yieldparam memo [Object] Any extension-specific value which will be passed to {#after_resolve} later
|
48
|
+
# @return [Object] The return value for this field.
|
49
|
+
def resolve(object:, arguments:, context:)
|
50
|
+
yield(object, arguments, nil)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Called after {#field} was resolved, and after any lazy values (like `Promise`s) were synced,
|
54
|
+
# but before the value was added to the GraphQL response.
|
55
|
+
#
|
56
|
+
# Whatever this hook returns will be used as the return value.
|
57
|
+
#
|
58
|
+
# @param object [Object] The object the field is being resolved on
|
59
|
+
# @param arguments [Hash] Ruby keyword arguments for resolving this field
|
60
|
+
# @param context [Query::Context] the context for this query
|
61
|
+
# @param value [Object] Whatever the field previously returned
|
62
|
+
# @param memo [Object] The third value yielded by {#resolve}, or `nil` if there wasn't one
|
63
|
+
# @return [Object] The return value for this field.
|
64
|
+
def after_resolve(object:, arguments:, context:, value:, memo:)
|
65
|
+
value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
module FindInheritedValue
|
5
|
+
module EmptyObjects
|
6
|
+
EMPTY_HASH = {}.freeze
|
7
|
+
EMPTY_ARRAY = [].freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.extended(child_cls)
|
11
|
+
child_cls.singleton_class.include(EmptyObjects)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(child_cls)
|
15
|
+
child_cls.include(EmptyObjects)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def find_inherited_value(method_name, default_value = nil)
|
21
|
+
if self.is_a?(Class)
|
22
|
+
superclass.respond_to?(method_name, true) ? superclass.send(method_name) : default_value
|
23
|
+
else
|
24
|
+
ancestors_except_self = ancestors
|
25
|
+
ancestors_except_self.delete(self)
|
26
|
+
ancestors_except_self.each do |ancestor|
|
27
|
+
if ancestor.respond_to?(method_name, true)
|
28
|
+
return ancestor.send(method_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
default_value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# Find schema members using string paths
|
6
|
+
#
|
7
|
+
# @example Finding object types
|
8
|
+
# MySchema.find("SomeObjectType")
|
9
|
+
#
|
10
|
+
# @example Finding fields
|
11
|
+
# MySchema.find("SomeObjectType.myField")
|
12
|
+
#
|
13
|
+
# @example Finding arguments
|
14
|
+
# MySchema.find("SomeObjectType.myField.anArgument")
|
15
|
+
#
|
16
|
+
# @example Finding directives
|
17
|
+
# MySchema.find("@include")
|
18
|
+
#
|
19
|
+
class Finder
|
20
|
+
class MemberNotFoundError < ArgumentError; end
|
21
|
+
|
22
|
+
def initialize(schema)
|
23
|
+
@schema = schema
|
24
|
+
end
|
25
|
+
|
26
|
+
def find(path)
|
27
|
+
path = path.split(".")
|
28
|
+
type_or_directive = path.shift
|
29
|
+
|
30
|
+
if type_or_directive.start_with?("@")
|
31
|
+
directive = schema.directives[type_or_directive[1..-1]]
|
32
|
+
|
33
|
+
if directive.nil?
|
34
|
+
raise MemberNotFoundError, "Could not find directive `#{type_or_directive}` in schema."
|
35
|
+
end
|
36
|
+
|
37
|
+
return directive if path.empty?
|
38
|
+
|
39
|
+
find_in_directive(directive, path: path)
|
40
|
+
else
|
41
|
+
type = schema.get_type(type_or_directive) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
42
|
+
|
43
|
+
if type.nil?
|
44
|
+
raise MemberNotFoundError, "Could not find type `#{type_or_directive}` in schema."
|
45
|
+
end
|
46
|
+
|
47
|
+
return type if path.empty?
|
48
|
+
|
49
|
+
find_in_type(type, path: path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :schema
|
56
|
+
|
57
|
+
def find_in_directive(directive, path:)
|
58
|
+
argument_name = path.shift
|
59
|
+
argument = directive.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
60
|
+
|
61
|
+
if argument.nil?
|
62
|
+
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on directive #{directive}."
|
63
|
+
end
|
64
|
+
|
65
|
+
argument
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_in_type(type, path:)
|
69
|
+
case type.kind.name
|
70
|
+
when "OBJECT"
|
71
|
+
find_in_fields_type(type, kind: "object", path: path)
|
72
|
+
when "INTERFACE"
|
73
|
+
find_in_fields_type(type, kind: "interface", path: path)
|
74
|
+
when "INPUT_OBJECT"
|
75
|
+
find_in_input_object(type, path: path)
|
76
|
+
when "UNION"
|
77
|
+
# Error out if path that was provided is too long
|
78
|
+
# i.e UnionType.PossibleType.aField
|
79
|
+
# Use PossibleType.aField instead.
|
80
|
+
if invalid = path.first
|
81
|
+
raise MemberNotFoundError, "Cannot select union possible type `#{invalid}`. Select the type directly instead."
|
82
|
+
end
|
83
|
+
when "ENUM"
|
84
|
+
find_in_enum_type(type, path: path)
|
85
|
+
else
|
86
|
+
raise "Unexpected find_in_type: #{type.inspect} (#{path})"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_in_fields_type(type, kind:, path:)
|
91
|
+
field_name = path.shift
|
92
|
+
field = schema.get_field(type, field_name)
|
93
|
+
|
94
|
+
if field.nil?
|
95
|
+
raise MemberNotFoundError, "Could not find field `#{field_name}` on #{kind} type `#{type.graphql_name}`."
|
96
|
+
end
|
97
|
+
|
98
|
+
return field if path.empty?
|
99
|
+
|
100
|
+
find_in_field(field, path: path)
|
101
|
+
end
|
102
|
+
|
103
|
+
def find_in_field(field, path:)
|
104
|
+
argument_name = path.shift
|
105
|
+
argument = field.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
106
|
+
|
107
|
+
if argument.nil?
|
108
|
+
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
|
109
|
+
end
|
110
|
+
|
111
|
+
# Error out if path that was provided is too long
|
112
|
+
# i.e Type.field.argument.somethingBad
|
113
|
+
if invalid = path.first
|
114
|
+
raise MemberNotFoundError, "Cannot select member `#{invalid}` on a field."
|
115
|
+
end
|
116
|
+
|
117
|
+
argument
|
118
|
+
end
|
119
|
+
|
120
|
+
def find_in_input_object(input_object, path:)
|
121
|
+
field_name = path.shift
|
122
|
+
input_field = input_object.get_argument(field_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
123
|
+
|
124
|
+
if input_field.nil?
|
125
|
+
raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object.graphql_name}`."
|
126
|
+
end
|
127
|
+
|
128
|
+
# Error out if path that was provided is too long
|
129
|
+
# i.e InputType.inputField.bad
|
130
|
+
if invalid = path.first
|
131
|
+
raise MemberNotFoundError, "Cannot select member `#{invalid}` on an input field."
|
132
|
+
end
|
133
|
+
|
134
|
+
input_field
|
135
|
+
end
|
136
|
+
|
137
|
+
def find_in_enum_type(enum_type, path:)
|
138
|
+
value_name = path.shift
|
139
|
+
enum_value = enum_type.enum_values.find { |v| v.graphql_name == value_name } # rubocop:disable Development/ContextIsPassedCop -- build-time, not runtime
|
140
|
+
|
141
|
+
if enum_value.nil?
|
142
|
+
raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type.graphql_name}`."
|
143
|
+
end
|
144
|
+
|
145
|
+
# Error out if path that was provided is too long
|
146
|
+
# i.e Enum.VALUE.wat
|
147
|
+
if invalid = path.first
|
148
|
+
raise MemberNotFoundError, "Cannot select member `#{invalid}` on an enum value."
|
149
|
+
end
|
150
|
+
|
151
|
+
enum_value
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class InputObject < GraphQL::Schema::Member
|
5
|
+
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
|
+
extend Forwardable
|
7
|
+
extend GraphQL::Schema::Member::HasArguments
|
8
|
+
extend GraphQL::Schema::Member::HasArguments::ArgumentObjectLoader
|
9
|
+
extend GraphQL::Schema::Member::ValidatesInput
|
10
|
+
extend GraphQL::Schema::Member::HasValidators
|
11
|
+
|
12
|
+
include GraphQL::Dig
|
13
|
+
|
14
|
+
# @return [GraphQL::Query::Context] The context for this query
|
15
|
+
attr_reader :context
|
16
|
+
# @return [GraphQL::Query::Arguments, GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
17
|
+
attr_reader :arguments
|
18
|
+
|
19
|
+
# Ruby-like hash behaviors, read-only
|
20
|
+
def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
|
21
|
+
|
22
|
+
def initialize(arguments = nil, ruby_kwargs: nil, context:, defaults_used:)
|
23
|
+
@context = context
|
24
|
+
if ruby_kwargs
|
25
|
+
@ruby_style_hash = ruby_kwargs
|
26
|
+
@arguments = arguments
|
27
|
+
else
|
28
|
+
@arguments = self.class.arguments_class.new(arguments, context: context, defaults_used: defaults_used)
|
29
|
+
# Symbolized, underscored hash:
|
30
|
+
@ruby_style_hash = @arguments.to_kwargs
|
31
|
+
end
|
32
|
+
# Apply prepares, not great to have it duplicated here.
|
33
|
+
maybe_lazies = []
|
34
|
+
self.class.arguments(context).each_value do |arg_defn|
|
35
|
+
ruby_kwargs_key = arg_defn.keyword
|
36
|
+
|
37
|
+
if @ruby_style_hash.key?(ruby_kwargs_key)
|
38
|
+
loads = arg_defn.loads
|
39
|
+
# Resolvers do this loading themselves;
|
40
|
+
# With the interpreter, it's done during `coerce_arguments`
|
41
|
+
if loads && !arg_defn.from_resolver? && !context.interpreter?
|
42
|
+
value = @ruby_style_hash[ruby_kwargs_key]
|
43
|
+
loaded_value = arg_defn.load_and_authorize_value(self, value, context)
|
44
|
+
maybe_lazies << context.schema.after_lazy(loaded_value) do |loaded_value|
|
45
|
+
overwrite_argument(ruby_kwargs_key, loaded_value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Weirdly, procs are applied during coercion, but not methods.
|
50
|
+
# Probably because these methods require a `self`.
|
51
|
+
if arg_defn.prepare.is_a?(Symbol) || context.nil? || !context.interpreter?
|
52
|
+
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
53
|
+
overwrite_argument(ruby_kwargs_key, prepared_value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
@maybe_lazies = maybe_lazies
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_h
|
62
|
+
unwrap_value(@ruby_style_hash)
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_hash
|
66
|
+
to_h
|
67
|
+
end
|
68
|
+
|
69
|
+
def prepare
|
70
|
+
if @context
|
71
|
+
@context.schema.after_any_lazies(@maybe_lazies) do
|
72
|
+
object = @context[:current_object]
|
73
|
+
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
74
|
+
Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
|
75
|
+
self
|
76
|
+
end
|
77
|
+
else
|
78
|
+
self
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def unwrap_value(value)
|
83
|
+
case value
|
84
|
+
when Array
|
85
|
+
value.map { |item| unwrap_value(item) }
|
86
|
+
when Hash
|
87
|
+
value.reduce({}) do |h, (key, value)|
|
88
|
+
h.merge!(key => unwrap_value(value))
|
89
|
+
end
|
90
|
+
when InputObject
|
91
|
+
value.to_h
|
92
|
+
else
|
93
|
+
value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Lookup a key on this object, it accepts new-style underscored symbols
|
98
|
+
# Or old-style camelized identifiers.
|
99
|
+
# @param key [Symbol, String]
|
100
|
+
def [](key)
|
101
|
+
if @ruby_style_hash.key?(key)
|
102
|
+
@ruby_style_hash[key]
|
103
|
+
elsif @arguments
|
104
|
+
@arguments[key]
|
105
|
+
else
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def key?(key)
|
111
|
+
@ruby_style_hash.key?(key) || (@arguments && @arguments.key?(key)) || false
|
112
|
+
end
|
113
|
+
|
114
|
+
# A copy of the Ruby-style hash
|
115
|
+
def to_kwargs
|
116
|
+
@ruby_style_hash.dup
|
117
|
+
end
|
118
|
+
|
119
|
+
class << self
|
120
|
+
# @return [Class<GraphQL::Arguments>]
|
121
|
+
attr_accessor :arguments_class
|
122
|
+
|
123
|
+
def argument(*args, **kwargs, &block)
|
124
|
+
argument_defn = super(*args, **kwargs, &block)
|
125
|
+
# Add a method access
|
126
|
+
method_name = argument_defn.keyword
|
127
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
128
|
+
def #{method_name}
|
129
|
+
self[#{method_name.inspect}]
|
130
|
+
end
|
131
|
+
RUBY
|
132
|
+
argument_defn
|
133
|
+
end
|
134
|
+
|
135
|
+
def to_graphql
|
136
|
+
type_defn = GraphQL::InputObjectType.new
|
137
|
+
type_defn.name = graphql_name
|
138
|
+
type_defn.description = description
|
139
|
+
type_defn.metadata[:type_class] = self
|
140
|
+
type_defn.mutation = mutation
|
141
|
+
type_defn.ast_node = ast_node
|
142
|
+
all_argument_definitions.each do |arg|
|
143
|
+
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
144
|
+
end
|
145
|
+
# Make a reference to a classic-style Arguments class
|
146
|
+
self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
|
147
|
+
# But use this InputObject class at runtime
|
148
|
+
type_defn.arguments_class = self
|
149
|
+
type_defn
|
150
|
+
end
|
151
|
+
|
152
|
+
def kind
|
153
|
+
GraphQL::TypeKinds::INPUT_OBJECT
|
154
|
+
end
|
155
|
+
|
156
|
+
# @api private
|
157
|
+
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
|
158
|
+
|
159
|
+
def validate_non_null_input(input, ctx)
|
160
|
+
result = GraphQL::Query::InputValidationResult.new
|
161
|
+
|
162
|
+
warden = ctx.warden
|
163
|
+
|
164
|
+
if input.is_a?(Array)
|
165
|
+
result.add_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
166
|
+
return result
|
167
|
+
end
|
168
|
+
|
169
|
+
if !(input.respond_to?(:to_h) || input.respond_to?(:to_unsafe_h))
|
170
|
+
# We're not sure it'll act like a hash, so reject it:
|
171
|
+
result.add_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
172
|
+
return result
|
173
|
+
end
|
174
|
+
|
175
|
+
# Inject missing required arguments
|
176
|
+
missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
|
177
|
+
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
178
|
+
m[argument_name] = nil
|
179
|
+
end
|
180
|
+
|
181
|
+
m
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
[input, missing_required_inputs].each do |args_to_validate|
|
186
|
+
args_to_validate.each do |argument_name, value|
|
187
|
+
argument = warden.get_argument(self, argument_name)
|
188
|
+
# Items in the input that are unexpected
|
189
|
+
unless argument
|
190
|
+
result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
|
191
|
+
next
|
192
|
+
end
|
193
|
+
# Items in the input that are expected, but have invalid values
|
194
|
+
argument_result = argument.type.validate_input(value, ctx)
|
195
|
+
result.merge_result!(argument_name, argument_result) unless argument_result.valid?
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
result
|
200
|
+
end
|
201
|
+
|
202
|
+
def coerce_input(value, ctx)
|
203
|
+
if value.nil?
|
204
|
+
return nil
|
205
|
+
end
|
206
|
+
|
207
|
+
arguments = coerce_arguments(nil, value, ctx)
|
208
|
+
|
209
|
+
ctx.schema.after_lazy(arguments) do |resolved_arguments|
|
210
|
+
if resolved_arguments.is_a?(GraphQL::Error)
|
211
|
+
raise resolved_arguments
|
212
|
+
else
|
213
|
+
input_obj_instance = self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
|
214
|
+
input_obj_instance.prepare
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# It's funny to think of a _result_ of an input object.
|
220
|
+
# This is used for rendering the default value in introspection responses.
|
221
|
+
def coerce_result(value, ctx)
|
222
|
+
# Allow the application to provide values as :snake_symbols, and convert them to the camelStrings
|
223
|
+
value = value.reduce({}) { |memo, (k, v)| memo[Member::BuildType.camelize(k.to_s)] = v; memo }
|
224
|
+
|
225
|
+
result = {}
|
226
|
+
|
227
|
+
arguments(ctx).each do |input_key, input_field_defn|
|
228
|
+
input_value = value[input_key]
|
229
|
+
if value.key?(input_key)
|
230
|
+
result[input_key] = if input_value.nil?
|
231
|
+
nil
|
232
|
+
else
|
233
|
+
input_field_defn.type.coerce_result(input_value, ctx)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
result
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
def overwrite_argument(key, value)
|
245
|
+
# Argument keywords come in frozen from the interpreter, dup them before modifying them.
|
246
|
+
if @ruby_style_hash.frozen?
|
247
|
+
@ruby_style_hash = @ruby_style_hash.dup
|
248
|
+
end
|
249
|
+
@ruby_style_hash[key] = value
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
module Interface
|
5
|
+
include GraphQL::Schema::Member::GraphQLTypeNames
|
6
|
+
module DefinitionMethods
|
7
|
+
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
8
|
+
include GraphQL::Relay::TypeExtensions
|
9
|
+
include GraphQL::Schema::Member::BaseDSLMethods
|
10
|
+
# ConfigurationExtension's responsibilities are in `def included` below
|
11
|
+
include GraphQL::Schema::Member::TypeSystemHelpers
|
12
|
+
include GraphQL::Schema::Member::HasFields
|
13
|
+
include GraphQL::Schema::Member::HasPath
|
14
|
+
include GraphQL::Schema::Member::RelayShortcuts
|
15
|
+
include GraphQL::Schema::Member::Scoped
|
16
|
+
include GraphQL::Schema::Member::HasAstNode
|
17
|
+
include GraphQL::Schema::Member::HasUnresolvedTypeError
|
18
|
+
include GraphQL::Schema::Member::HasDirectives
|
19
|
+
include GraphQL::Schema::Member::HasInterfaces
|
20
|
+
|
21
|
+
# Methods defined in this block will be:
|
22
|
+
# - Added as class methods to this interface
|
23
|
+
# - Added as class methods to all child interfaces
|
24
|
+
def definition_methods(&block)
|
25
|
+
self::DefinitionMethods.module_eval(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @see {Schema::Warden} hides interfaces without visible implementations
|
29
|
+
def visible?(context)
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
# The interface is accessible if any of its possible types are accessible
|
34
|
+
def accessible?(context)
|
35
|
+
context.schema.possible_types(self, context).each do |type|
|
36
|
+
if context.schema.accessible?(type, context)
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
def type_membership_class(membership_class = nil)
|
44
|
+
if membership_class
|
45
|
+
@type_membership_class = membership_class
|
46
|
+
else
|
47
|
+
@type_membership_class || find_inherited_value(:type_membership_class, GraphQL::Schema::TypeMembership)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Here's the tricky part. Make sure behavior keeps making its way down the inheritance chain.
|
52
|
+
def included(child_class)
|
53
|
+
if !child_class.is_a?(Class)
|
54
|
+
# In this case, it's been included into another interface.
|
55
|
+
# This is how interface inheritance is implemented
|
56
|
+
|
57
|
+
# We need this before we can call `own_interfaces`
|
58
|
+
child_class.extend(Schema::Interface::DefinitionMethods)
|
59
|
+
|
60
|
+
child_class.type_membership_class(self.type_membership_class)
|
61
|
+
child_class.ancestors.reverse_each do |ancestor|
|
62
|
+
if ancestor.const_defined?(:DefinitionMethods)
|
63
|
+
child_class.extend(ancestor::DefinitionMethods)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Use an instance variable to tell whether it's been included previously or not;
|
68
|
+
# You can't use constant detection because constants are brought into scope
|
69
|
+
# by `include`, which has already happened at this point.
|
70
|
+
if !child_class.instance_variable_defined?(:@_definition_methods)
|
71
|
+
defn_methods_module = Module.new
|
72
|
+
child_class.instance_variable_set(:@_definition_methods, defn_methods_module)
|
73
|
+
child_class.const_set(:DefinitionMethods, defn_methods_module)
|
74
|
+
child_class.extend(child_class::DefinitionMethods)
|
75
|
+
end
|
76
|
+
child_class.introspection(introspection)
|
77
|
+
child_class.description(description)
|
78
|
+
# If interfaces are mixed into each other, only define this class once
|
79
|
+
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
80
|
+
add_unresolved_type_error(child_class)
|
81
|
+
end
|
82
|
+
elsif child_class < GraphQL::Schema::Object
|
83
|
+
# This is being included into an object type, make sure it's using `implements(...)`
|
84
|
+
backtrace_line = caller(0, 10).find { |line| line.include?("schema/member/has_interfaces.rb") && line.include?("in `implements'")}
|
85
|
+
if !backtrace_line
|
86
|
+
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
super
|
91
|
+
end
|
92
|
+
|
93
|
+
def orphan_types(*types)
|
94
|
+
if types.any?
|
95
|
+
@orphan_types = types
|
96
|
+
else
|
97
|
+
all_orphan_types = @orphan_types || []
|
98
|
+
all_orphan_types += super if defined?(super)
|
99
|
+
all_orphan_types.uniq
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_graphql
|
104
|
+
type_defn = GraphQL::InterfaceType.new
|
105
|
+
type_defn.name = graphql_name
|
106
|
+
type_defn.description = description
|
107
|
+
type_defn.orphan_types = orphan_types
|
108
|
+
type_defn.type_membership_class = self.type_membership_class
|
109
|
+
type_defn.ast_node = ast_node
|
110
|
+
fields.each do |field_name, field_inst| # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
111
|
+
field_defn = field_inst.graphql_definition
|
112
|
+
type_defn.fields[field_defn.name] = field_defn # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
113
|
+
end
|
114
|
+
type_defn.metadata[:type_class] = self
|
115
|
+
if respond_to?(:resolve_type)
|
116
|
+
type_defn.resolve_type = method(:resolve_type)
|
117
|
+
end
|
118
|
+
type_defn
|
119
|
+
end
|
120
|
+
|
121
|
+
def kind
|
122
|
+
GraphQL::TypeKinds::INTERFACE
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Extend this _after_ `DefinitionMethods` is defined, so it will be used
|
127
|
+
extend GraphQL::Schema::Member::AcceptsDefinition
|
128
|
+
|
129
|
+
extend DefinitionMethods
|
130
|
+
|
131
|
+
def unwrap
|
132
|
+
self
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|