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,10 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Mutations
|
3
|
+
class BaseMutation < GraphQL::Schema::RelayClassicMutation
|
4
|
+
argument_class Types::BaseArgument
|
5
|
+
field_class Types::BaseField
|
6
|
+
input_object_class Types::BaseInputObject
|
7
|
+
object_class Types::BaseObject
|
8
|
+
end
|
9
|
+
end
|
10
|
+
<% end -%>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
class GraphqlController < ApplicationController
|
3
|
+
# If accessing from outside this domain, nullify the session
|
4
|
+
# This allows for outside API access while preventing CSRF attacks,
|
5
|
+
# but you'll have to authenticate your user separately
|
6
|
+
# protect_from_forgery with: :null_session
|
7
|
+
|
8
|
+
def execute
|
9
|
+
variables = prepare_variables(params[:variables])
|
10
|
+
query = params[:query]
|
11
|
+
operation_name = params[:operationName]
|
12
|
+
context = {
|
13
|
+
# Query context goes here, for example:
|
14
|
+
# current_user: current_user,
|
15
|
+
}
|
16
|
+
result = <%= schema_name %>.execute(query, variables: variables, context: context, operation_name: operation_name)
|
17
|
+
render json: result
|
18
|
+
rescue StandardError => e
|
19
|
+
raise e unless Rails.env.development?
|
20
|
+
handle_error_in_development(e)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Handle variables in form data, JSON body, or a blank value
|
26
|
+
def prepare_variables(variables_param)
|
27
|
+
case variables_param
|
28
|
+
when String
|
29
|
+
if variables_param.present?
|
30
|
+
JSON.parse(variables_param) || {}
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
when Hash
|
35
|
+
variables_param
|
36
|
+
when ActionController::Parameters
|
37
|
+
variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables.
|
38
|
+
when nil
|
39
|
+
{}
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Unexpected parameter: #{variables_param}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_error_in_development(e)
|
46
|
+
logger.error e.message
|
47
|
+
logger.error e.backtrace.join("\n")
|
48
|
+
|
49
|
+
render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} }, status: 500
|
50
|
+
end
|
51
|
+
end
|
52
|
+
<% end -%>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Loaders
|
3
|
+
class <%= class_name %> < GraphQL::Batch::Loader
|
4
|
+
# Define `initialize` to store grouping arguments, eg
|
5
|
+
#
|
6
|
+
# Loaders::<%= class_name %>.for(group).load(value)
|
7
|
+
#
|
8
|
+
# def initialize()
|
9
|
+
# end
|
10
|
+
|
11
|
+
# `keys` contains each key from `.load(key)`.
|
12
|
+
# Find the corresponding values, then
|
13
|
+
# call `fulfill(key, value)` or `fulfill(key, nil)`
|
14
|
+
# for each key.
|
15
|
+
def perform(keys)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
<% end -%>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Mutations
|
3
|
+
class <%= mutation_name %> < BaseMutation
|
4
|
+
# TODO: define return fields
|
5
|
+
# field :post, Types::PostType, null: false
|
6
|
+
|
7
|
+
# TODO: define arguments
|
8
|
+
# argument :name, String, required: true
|
9
|
+
|
10
|
+
# TODO: define resolve method
|
11
|
+
# def resolve(name:)
|
12
|
+
# { post: ... }
|
13
|
+
# end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
<% end -%>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Types
|
3
|
+
class MutationType < Types::BaseObject
|
4
|
+
# TODO: remove me
|
5
|
+
field :test_field, String, null: false,
|
6
|
+
description: "An example field added by the generator"
|
7
|
+
def test_field
|
8
|
+
"Hello World"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
<% end -%>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Types
|
3
|
+
class <%= type_ruby_name.split('::')[-1] %> < Types::BaseObject
|
4
|
+
<% if options.node %> implements GraphQL::Types::Relay::Node
|
5
|
+
<% end %><% normalized_fields.each do |f| %> <%= f.to_ruby %>
|
6
|
+
<% end %> end
|
7
|
+
end
|
8
|
+
<% end -%>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Types
|
3
|
+
class QueryType < Types::BaseObject
|
4
|
+
# Add root-level fields here.
|
5
|
+
# They will be entry points for queries on your schema.
|
6
|
+
|
7
|
+
# TODO: remove me
|
8
|
+
field :test_field, String, null: false,
|
9
|
+
description: "An example field added by the generator"
|
10
|
+
def test_field
|
11
|
+
"Hello World!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
<% end -%>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Types
|
3
|
+
class <%= type_ruby_name.split('::')[-1] %> < Types::BaseScalar
|
4
|
+
def self.coerce_input(input_value, context)
|
5
|
+
# Override this to prepare a client-provided GraphQL value for your Ruby code
|
6
|
+
input_value
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.coerce_result(ruby_value, context)
|
10
|
+
# Override this to serialize a Ruby value for the GraphQL response
|
11
|
+
ruby_value.to_s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
<% end -%>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
class <%= schema_name %> < GraphQL::Schema
|
3
|
+
query(Types::QueryType)
|
4
|
+
<% if options[:batch] %>
|
5
|
+
# GraphQL::Batch setup:
|
6
|
+
use GraphQL::Batch
|
7
|
+
<% else %>
|
8
|
+
# For batch-loading (see https://graphql-ruby.org/dataloader/overview.html)
|
9
|
+
use GraphQL::Dataloader
|
10
|
+
<% end %>
|
11
|
+
# GraphQL-Ruby calls this when something goes wrong while running a query:
|
12
|
+
def self.type_error(err, context)
|
13
|
+
# if err.is_a?(GraphQL::InvalidNullError)
|
14
|
+
# # report to your bug tracker here
|
15
|
+
# return nil
|
16
|
+
# end
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
# Union and Interface Resolution
|
21
|
+
def self.resolve_type(abstract_type, obj, ctx)
|
22
|
+
# TODO: Implement this method
|
23
|
+
# to return the correct GraphQL object type for `obj`
|
24
|
+
raise(GraphQL::RequiredImplementationMissingError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
<% end -%>
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rails/generators'
|
3
|
+
require 'rails/generators/base'
|
4
|
+
require 'graphql'
|
5
|
+
require 'active_support'
|
6
|
+
require 'active_support/core_ext/string/inflections'
|
7
|
+
require_relative 'core'
|
8
|
+
|
9
|
+
module Graphql
|
10
|
+
module Generators
|
11
|
+
class TypeGeneratorBase < Rails::Generators::Base
|
12
|
+
include Core
|
13
|
+
|
14
|
+
argument :type_name,
|
15
|
+
type: :string,
|
16
|
+
banner: "TypeName",
|
17
|
+
desc: "Name of this object type (expressed as Ruby or GraphQL)"
|
18
|
+
|
19
|
+
# Take a type expression in any combination of GraphQL or Ruby styles
|
20
|
+
# and return it in a specified output style
|
21
|
+
# TODO: nullability / list with `mode: :graphql` doesn't work
|
22
|
+
# @param type_expresson [String]
|
23
|
+
# @param mode [Symbol]
|
24
|
+
# @param null [Boolean]
|
25
|
+
# @return [(String, Boolean)] The type expression, followed by `null:` value
|
26
|
+
def self.normalize_type_expression(type_expression, mode:, null: true)
|
27
|
+
if type_expression.start_with?("!")
|
28
|
+
normalize_type_expression(type_expression[1..-1], mode: mode, null: false)
|
29
|
+
elsif type_expression.end_with?("!")
|
30
|
+
normalize_type_expression(type_expression[0..-2], mode: mode, null: false)
|
31
|
+
elsif type_expression.start_with?("[") && type_expression.end_with?("]")
|
32
|
+
name, is_null = normalize_type_expression(type_expression[1..-2], mode: mode, null: null)
|
33
|
+
["[#{name}]", is_null]
|
34
|
+
elsif type_expression.end_with?("Type")
|
35
|
+
normalize_type_expression(type_expression[0..-5], mode: mode, null: null)
|
36
|
+
elsif type_expression.start_with?("Types::")
|
37
|
+
normalize_type_expression(type_expression[7..-1], mode: mode, null: null)
|
38
|
+
elsif type_expression.start_with?("types.")
|
39
|
+
normalize_type_expression(type_expression[6..-1], mode: mode, null: null)
|
40
|
+
else
|
41
|
+
case mode
|
42
|
+
when :ruby
|
43
|
+
case type_expression
|
44
|
+
when "Int"
|
45
|
+
["Integer", null]
|
46
|
+
when "Integer", "Float", "Boolean", "String", "ID"
|
47
|
+
[type_expression, null]
|
48
|
+
else
|
49
|
+
["Types::#{type_expression.camelize}Type", null]
|
50
|
+
end
|
51
|
+
when :graphql
|
52
|
+
[type_expression.camelize, null]
|
53
|
+
else
|
54
|
+
raise "Unexpected normalize mode: #{mode}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# @return [String] The user-provided type name, normalized to Ruby code
|
62
|
+
def type_ruby_name
|
63
|
+
@type_ruby_name ||= self.class.normalize_type_expression(type_name, mode: :ruby)[0]
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [String] The user-provided type name, as a GraphQL name
|
67
|
+
def type_graphql_name
|
68
|
+
@type_graphql_name ||= self.class.normalize_type_expression(type_name, mode: :graphql)[0]
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [String] The user-provided type name, as a file name (without extension)
|
72
|
+
def type_file_name
|
73
|
+
@type_file_name ||= "#{type_graphql_name}Type".underscore
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Array<NormalizedField>] User-provided fields, in `(name, Ruby type name)` pairs
|
77
|
+
def normalized_fields
|
78
|
+
@normalized_fields ||= fields.map { |f|
|
79
|
+
name, raw_type = f.split(":", 2)
|
80
|
+
type_expr, null = self.class.normalize_type_expression(raw_type, mode: :ruby)
|
81
|
+
NormalizedField.new(name, type_expr, null)
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
class NormalizedField
|
86
|
+
def initialize(name, type_expr, null)
|
87
|
+
@name = name
|
88
|
+
@type_expr = type_expr
|
89
|
+
@null = null
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_ruby
|
93
|
+
"field :#{@name}, #{@type_expr}, null: #{@null}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'generators/graphql/type_generator'
|
3
|
+
|
4
|
+
module Graphql
|
5
|
+
module Generators
|
6
|
+
# Generate a union type by name
|
7
|
+
# with the specified member types.
|
8
|
+
#
|
9
|
+
# ```
|
10
|
+
# rails g graphql:union SearchResultType ImageType AudioType
|
11
|
+
# ```
|
12
|
+
class UnionGenerator < TypeGeneratorBase
|
13
|
+
desc "Create a GraphQL::UnionType with the given name and possible types"
|
14
|
+
source_root File.expand_path('../templates', __FILE__)
|
15
|
+
|
16
|
+
argument :possible_types,
|
17
|
+
type: :array,
|
18
|
+
default: [],
|
19
|
+
banner: "type type ...",
|
20
|
+
desc: "Possible types for this union (expressed as Ruby or GraphQL)"
|
21
|
+
|
22
|
+
def create_type_file
|
23
|
+
template "union.erb", "#{options[:directory]}/types/#{type_file_name}.rb"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def normalized_possible_types
|
29
|
+
possible_types.map { |t| self.class.normalize_type_expression(t, mode: :ruby)[0] }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Analysis
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def use(schema_class)
|
7
|
+
schema = schema_class.is_a?(Class) ? schema_class : schema_class.target
|
8
|
+
schema.analysis_engine = self
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [void]
|
12
|
+
def analyze_multiplex(multiplex, analyzers)
|
13
|
+
multiplex.trace("analyze_multiplex", { multiplex: multiplex }) do
|
14
|
+
reducer_states = analyzers.map { |r| ReducerState.new(r, multiplex) }
|
15
|
+
query_results = multiplex.queries.map do |query|
|
16
|
+
if query.valid?
|
17
|
+
analyze_query(query, query.analyzers, multiplex_states: reducer_states)
|
18
|
+
else
|
19
|
+
[]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
multiplex_results = reducer_states.map(&:finalize_reducer)
|
24
|
+
multiplex_errors = analysis_errors(multiplex_results)
|
25
|
+
|
26
|
+
multiplex.queries.each_with_index do |query, idx|
|
27
|
+
query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
# Visit `query`'s internal representation, calling `analyzers` along the way.
|
34
|
+
#
|
35
|
+
# - First, query analyzers are filtered down by calling `.analyze?(query)`, if they respond to that method
|
36
|
+
# - Then, query analyzers are initialized by calling `.initial_value(query)`, if they respond to that method.
|
37
|
+
# - Then, they receive `.call(memo, visit_type, irep_node)`, where visit type is `:enter` or `:leave`.
|
38
|
+
# - Last, they receive `.final_value(memo)`, if they respond to that method.
|
39
|
+
#
|
40
|
+
# It returns an array of final `memo` values in the order that `analyzers` were passed in.
|
41
|
+
#
|
42
|
+
# @param query [GraphQL::Query]
|
43
|
+
# @param analyzers [Array<#call>] Objects that respond to `#call(memo, visit_type, irep_node)`
|
44
|
+
# @return [Array<Any>] Results from those analyzers
|
45
|
+
def analyze_query(query, analyzers, multiplex_states: [])
|
46
|
+
GraphQL::Deprecation.warn "Legacy analysis will be removed in GraphQL-Ruby 2.0, please upgrade to AST Analysis: https://graphql-ruby.org/queries/ast_analysis.html (schema: #{query.schema})"
|
47
|
+
|
48
|
+
query.trace("analyze_query", { query: query }) do
|
49
|
+
analyzers_to_run = analyzers.select do |analyzer|
|
50
|
+
if analyzer.respond_to?(:analyze?)
|
51
|
+
analyzer.analyze?(query)
|
52
|
+
else
|
53
|
+
true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
reducer_states = analyzers_to_run.map { |r| ReducerState.new(r, query) } + multiplex_states
|
58
|
+
|
59
|
+
irep = query.internal_representation
|
60
|
+
|
61
|
+
irep.operation_definitions.each do |name, op_node|
|
62
|
+
reduce_node(op_node, reducer_states)
|
63
|
+
end
|
64
|
+
|
65
|
+
reducer_states.map(&:finalize_reducer)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
module_function
|
72
|
+
|
73
|
+
# Enter the node, visit its children, then leave the node.
|
74
|
+
def reduce_node(irep_node, reducer_states)
|
75
|
+
visit_analyzers(:enter, irep_node, reducer_states)
|
76
|
+
|
77
|
+
irep_node.typed_children.each do |type_defn, children|
|
78
|
+
children.each do |name, child_irep_node|
|
79
|
+
reduce_node(child_irep_node, reducer_states)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
visit_analyzers(:leave, irep_node, reducer_states)
|
84
|
+
end
|
85
|
+
|
86
|
+
def visit_analyzers(visit_type, irep_node, reducer_states)
|
87
|
+
reducer_states.each do |reducer_state|
|
88
|
+
next_memo = reducer_state.call(visit_type, irep_node)
|
89
|
+
|
90
|
+
reducer_state.memo = next_memo
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def analysis_errors(results)
|
95
|
+
results.flatten.select { |r| r.is_a?(GraphQL::AnalysisError) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Analysis
|
4
|
+
module AST
|
5
|
+
# Query analyzer for query ASTs. Query analyzers respond to visitor style methods
|
6
|
+
# but are prefixed by `enter` and `leave`.
|
7
|
+
#
|
8
|
+
# When an analyzer is initialized with a Multiplex, you can always get the current query from
|
9
|
+
# `visitor.query` in the visit methods.
|
10
|
+
#
|
11
|
+
# @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
|
12
|
+
class Analyzer
|
13
|
+
def initialize(subject)
|
14
|
+
@subject = subject
|
15
|
+
|
16
|
+
if subject.is_a?(GraphQL::Query)
|
17
|
+
@query = subject
|
18
|
+
@multiplex = nil
|
19
|
+
else
|
20
|
+
@multiplex = subject
|
21
|
+
@query = nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Analyzer hook to decide at analysis time whether a query should
|
26
|
+
# be analyzed or not.
|
27
|
+
# @return [Boolean] If the query should be analyzed or not
|
28
|
+
def analyze?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
# The result for this analyzer. Returning {GraphQL::AnalysisError} results
|
33
|
+
# in a query error.
|
34
|
+
# @return [Any] The analyzer result
|
35
|
+
def result
|
36
|
+
raise GraphQL::RequiredImplementationMissingError
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
private
|
41
|
+
|
42
|
+
def build_visitor_hooks(member_name)
|
43
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
44
|
+
def on_enter_#{member_name}(node, parent, visitor)
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_leave_#{member_name}(node, parent, visitor)
|
48
|
+
end
|
49
|
+
EOS
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
build_visitor_hooks :argument
|
54
|
+
build_visitor_hooks :directive
|
55
|
+
build_visitor_hooks :document
|
56
|
+
build_visitor_hooks :enum
|
57
|
+
build_visitor_hooks :field
|
58
|
+
build_visitor_hooks :fragment_spread
|
59
|
+
build_visitor_hooks :inline_fragment
|
60
|
+
build_visitor_hooks :input_object
|
61
|
+
build_visitor_hooks :list_type
|
62
|
+
build_visitor_hooks :non_null_type
|
63
|
+
build_visitor_hooks :null_value
|
64
|
+
build_visitor_hooks :operation_definition
|
65
|
+
build_visitor_hooks :type_name
|
66
|
+
build_visitor_hooks :variable_definition
|
67
|
+
build_visitor_hooks :variable_identifier
|
68
|
+
build_visitor_hooks :abstract_node
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
# @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
|
73
|
+
attr_reader :subject
|
74
|
+
|
75
|
+
# @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
|
76
|
+
# (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
|
77
|
+
attr_reader :query
|
78
|
+
|
79
|
+
# @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
|
80
|
+
attr_reader :multiplex
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Analysis
|
4
|
+
module AST
|
5
|
+
class FieldUsage < Analyzer
|
6
|
+
def initialize(query)
|
7
|
+
super
|
8
|
+
@used_fields = Set.new
|
9
|
+
@used_deprecated_fields = Set.new
|
10
|
+
@used_deprecated_arguments = Set.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_leave_field(node, parent, visitor)
|
14
|
+
field_defn = visitor.field_definition
|
15
|
+
field = "#{visitor.parent_type_definition.graphql_name}.#{field_defn.graphql_name}"
|
16
|
+
@used_fields << field
|
17
|
+
@used_deprecated_fields << field if field_defn.deprecation_reason
|
18
|
+
|
19
|
+
extract_deprecated_arguments(visitor.query.arguments_for(node, visitor.field_definition).argument_values)
|
20
|
+
end
|
21
|
+
|
22
|
+
def result
|
23
|
+
{
|
24
|
+
used_fields: @used_fields.to_a,
|
25
|
+
used_deprecated_fields: @used_deprecated_fields.to_a,
|
26
|
+
used_deprecated_arguments: @used_deprecated_arguments.to_a,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def extract_deprecated_arguments(argument_values)
|
33
|
+
argument_values.each_pair do |_argument_name, argument|
|
34
|
+
if argument.definition.deprecation_reason
|
35
|
+
@used_deprecated_arguments << argument.definition.path
|
36
|
+
end
|
37
|
+
|
38
|
+
if argument.definition.type.kind.input_object?
|
39
|
+
extract_deprecated_arguments(argument.value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
|
40
|
+
elsif argument.definition.type.list? && !argument.value.nil?
|
41
|
+
argument
|
42
|
+
.value
|
43
|
+
.select { |value| value.respond_to?(:arguments) }
|
44
|
+
.each { |value| extract_deprecated_arguments(value.arguments.argument_values) } # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative "./query_complexity"
|
3
|
+
module GraphQL
|
4
|
+
module Analysis
|
5
|
+
module AST
|
6
|
+
# Used under the hood to implement complexity validation,
|
7
|
+
# see {Schema#max_complexity} and {Query#max_complexity}
|
8
|
+
class MaxQueryComplexity < QueryComplexity
|
9
|
+
def result
|
10
|
+
return if subject.max_complexity.nil?
|
11
|
+
|
12
|
+
total_complexity = max_possible_complexity
|
13
|
+
|
14
|
+
if total_complexity > subject.max_complexity
|
15
|
+
GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Analysis
|
4
|
+
module AST
|
5
|
+
class MaxQueryDepth < QueryDepth
|
6
|
+
def result
|
7
|
+
configured_max_depth = if query
|
8
|
+
query.max_depth
|
9
|
+
else
|
10
|
+
multiplex.schema.max_depth
|
11
|
+
end
|
12
|
+
|
13
|
+
if configured_max_depth && @max_depth > configured_max_depth
|
14
|
+
GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|