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,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "set"
|
3
|
+
module GraphQL
|
4
|
+
class Subscriptions
|
5
|
+
# Serialization helpers for passing subscription data around.
|
6
|
+
# @api private
|
7
|
+
module Serialize
|
8
|
+
GLOBALID_KEY = "__gid__"
|
9
|
+
SYMBOL_KEY = "__sym__"
|
10
|
+
SYMBOL_KEYS_KEY = "__sym_keys__"
|
11
|
+
TIMESTAMP_KEY = "__timestamp__"
|
12
|
+
TIMESTAMP_FORMAT = "%Y-%m-%d %H:%M:%S.%N%z" # eg '2020-01-01 23:59:59.123456789+05:00'
|
13
|
+
OPEN_STRUCT_KEY = "__ostruct__"
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
# @param str [String] A serialized object from {.dump}
|
18
|
+
# @return [Object] An object equivalent to the one passed to {.dump}
|
19
|
+
def load(str)
|
20
|
+
parsed_obj = JSON.parse(str)
|
21
|
+
load_value(parsed_obj)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param obj [Object] Some subscription-related data to dump
|
25
|
+
# @return [String] The stringified object
|
26
|
+
def dump(obj)
|
27
|
+
JSON.generate(dump_value(obj), quirks_mode: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
# This is for turning objects into subscription scopes.
|
31
|
+
# It's a one-way transformation, can't reload this :'(
|
32
|
+
# @param obj [Object]
|
33
|
+
# @return [String]
|
34
|
+
def dump_recursive(obj)
|
35
|
+
case
|
36
|
+
when obj.is_a?(Array)
|
37
|
+
obj.map { |i| dump_recursive(i) }.join(':')
|
38
|
+
when obj.is_a?(Hash)
|
39
|
+
obj.map { |k, v| "#{dump_recursive(k)}:#{dump_recursive(v)}" }.join(":")
|
40
|
+
when obj.is_a?(GraphQL::Schema::InputObject)
|
41
|
+
dump_recursive(obj.to_h)
|
42
|
+
when obj.respond_to?(:to_gid_param)
|
43
|
+
obj.to_gid_param
|
44
|
+
when obj.respond_to?(:to_param)
|
45
|
+
obj.to_param
|
46
|
+
else
|
47
|
+
obj.to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
private
|
53
|
+
|
54
|
+
# @param value [Object] A parsed JSON object
|
55
|
+
# @return [Object] An object that load Global::Identification recursive
|
56
|
+
def load_value(value)
|
57
|
+
if value.is_a?(Array)
|
58
|
+
is_gids = (v1 = value[0]).is_a?(Hash) && v1.size == 1 && v1[GLOBALID_KEY]
|
59
|
+
if is_gids
|
60
|
+
# Assume it's an array of global IDs
|
61
|
+
ids = value.map { |v| v[GLOBALID_KEY] }
|
62
|
+
GlobalID::Locator.locate_many(ids)
|
63
|
+
else
|
64
|
+
value.map { |item| load_value(item) }
|
65
|
+
end
|
66
|
+
elsif value.is_a?(Hash)
|
67
|
+
if value.size == 1
|
68
|
+
case value.keys.first # there's only 1 key
|
69
|
+
when GLOBALID_KEY
|
70
|
+
GlobalID::Locator.locate(value[GLOBALID_KEY])
|
71
|
+
when SYMBOL_KEY
|
72
|
+
value[SYMBOL_KEY].to_sym
|
73
|
+
when TIMESTAMP_KEY
|
74
|
+
timestamp_class_name, timestamp_s = value[TIMESTAMP_KEY]
|
75
|
+
timestamp_class = Object.const_get(timestamp_class_name)
|
76
|
+
timestamp_class.strptime(timestamp_s, TIMESTAMP_FORMAT)
|
77
|
+
when OPEN_STRUCT_KEY
|
78
|
+
ostruct_values = load_value(value[OPEN_STRUCT_KEY])
|
79
|
+
OpenStruct.new(ostruct_values)
|
80
|
+
else
|
81
|
+
key = value.keys.first
|
82
|
+
{ key => load_value(value[key]) }
|
83
|
+
end
|
84
|
+
else
|
85
|
+
loaded_h = {}
|
86
|
+
sym_keys = value.fetch(SYMBOL_KEYS_KEY, [])
|
87
|
+
value.each do |k, v|
|
88
|
+
if k == SYMBOL_KEYS_KEY
|
89
|
+
next
|
90
|
+
end
|
91
|
+
if sym_keys.include?(k)
|
92
|
+
k = k.to_sym
|
93
|
+
end
|
94
|
+
loaded_h[k] = load_value(v)
|
95
|
+
end
|
96
|
+
loaded_h
|
97
|
+
end
|
98
|
+
else
|
99
|
+
value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param obj [Object] Some subscription-related data to dump
|
104
|
+
# @return [Object] The object that converted Global::Identification
|
105
|
+
def dump_value(obj)
|
106
|
+
if obj.is_a?(Array)
|
107
|
+
obj.map{|item| dump_value(item)}
|
108
|
+
elsif obj.is_a?(Hash)
|
109
|
+
symbol_keys = nil
|
110
|
+
dumped_h = {}
|
111
|
+
obj.each do |k, v|
|
112
|
+
dumped_h[k.to_s] = dump_value(v)
|
113
|
+
if k.is_a?(Symbol)
|
114
|
+
symbol_keys ||= Set.new
|
115
|
+
symbol_keys << k.to_s
|
116
|
+
end
|
117
|
+
end
|
118
|
+
if symbol_keys
|
119
|
+
dumped_h[SYMBOL_KEYS_KEY] = symbol_keys.to_a
|
120
|
+
end
|
121
|
+
dumped_h
|
122
|
+
elsif obj.is_a?(Symbol)
|
123
|
+
{ SYMBOL_KEY => obj.to_s }
|
124
|
+
elsif obj.respond_to?(:to_gid_param)
|
125
|
+
{GLOBALID_KEY => obj.to_gid_param}
|
126
|
+
elsif obj.is_a?(Date) || obj.is_a?(Time)
|
127
|
+
# DateTime extends Date; for TimeWithZone, call `.utc` first.
|
128
|
+
{ TIMESTAMP_KEY => [obj.class.name, obj.strftime(TIMESTAMP_FORMAT)] }
|
129
|
+
elsif obj.is_a?(OpenStruct)
|
130
|
+
{ OPEN_STRUCT_KEY => dump_value(obj.to_h) }
|
131
|
+
else
|
132
|
+
obj
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Subscriptions
|
5
|
+
# @api private
|
6
|
+
# @deprecated This module is no longer needed.
|
7
|
+
module SubscriptionRoot
|
8
|
+
def self.extended(child_cls)
|
9
|
+
GraphQL::Deprecation.warn "`extend GraphQL::Subscriptions::SubscriptionRoot` is no longer required; you can remove it from your Subscription type (#{child_cls})"
|
10
|
+
child_cls.include(InstanceMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
# This is for maintaining backwards compatibility:
|
14
|
+
# if a subscription field is created without a `subscription:` resolver class,
|
15
|
+
# then implement the method with the previous default behavior.
|
16
|
+
module InstanceMethods
|
17
|
+
def skip_subscription_root(*)
|
18
|
+
if context.query.subscription_update?
|
19
|
+
object
|
20
|
+
else
|
21
|
+
context.skip
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def field(*args, extensions: [], **rest, &block)
|
27
|
+
extensions += [Extension]
|
28
|
+
# Backwards-compat for schemas
|
29
|
+
if !rest[:subscription]
|
30
|
+
name = args.first
|
31
|
+
alias_method(name, :skip_subscription_root)
|
32
|
+
end
|
33
|
+
super(*args, extensions: extensions, **rest, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
class Extension < GraphQL::Schema::FieldExtension
|
37
|
+
def after_resolve(value:, context:, object:, arguments:, **rest)
|
38
|
+
if value.is_a?(GraphQL::ExecutionError)
|
39
|
+
value
|
40
|
+
elsif (events = context.namespace(:subscriptions)[:events])
|
41
|
+
# This is the first execution, so gather an Event
|
42
|
+
# for the backend to register:
|
43
|
+
event = Subscriptions::Event.new(
|
44
|
+
name: field.name,
|
45
|
+
arguments: arguments_without_field_extras(arguments: arguments),
|
46
|
+
context: context,
|
47
|
+
field: field,
|
48
|
+
)
|
49
|
+
events << event
|
50
|
+
value
|
51
|
+
elsif context.query.subscription_topic == Subscriptions::Event.serialize(
|
52
|
+
field.name,
|
53
|
+
arguments_without_field_extras(arguments: arguments),
|
54
|
+
field,
|
55
|
+
scope: (field.subscription_scope ? context[field.subscription_scope] : nil),
|
56
|
+
)
|
57
|
+
# This is a subscription update. The resolver returned `skip` if it should be skipped,
|
58
|
+
# or else it returned an object to resolve the update.
|
59
|
+
value
|
60
|
+
else
|
61
|
+
# This is a subscription update, but this event wasn't triggered.
|
62
|
+
context.skip
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def arguments_without_field_extras(arguments:)
|
69
|
+
arguments.dup.tap do |event_args|
|
70
|
+
field.extras.each { |k| event_args.delete(k) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "securerandom"
|
3
|
+
require "graphql/subscriptions/broadcast_analyzer"
|
4
|
+
require "graphql/subscriptions/event"
|
5
|
+
require "graphql/subscriptions/instrumentation"
|
6
|
+
require "graphql/subscriptions/serialize"
|
7
|
+
require "graphql/subscriptions/action_cable_subscriptions"
|
8
|
+
require "graphql/subscriptions/subscription_root"
|
9
|
+
require "graphql/subscriptions/default_subscription_resolve_extension"
|
10
|
+
|
11
|
+
module GraphQL
|
12
|
+
class Subscriptions
|
13
|
+
# Raised when either:
|
14
|
+
# - the triggered `event_name` doesn't match a field in the schema; or
|
15
|
+
# - one or more arguments don't match the field arguments
|
16
|
+
class InvalidTriggerError < GraphQL::Error
|
17
|
+
end
|
18
|
+
|
19
|
+
# Raised when either:
|
20
|
+
# - An initial subscription didn't have a value for `context[subscription_scope]`
|
21
|
+
# - Or, an update didn't pass `.trigger(..., scope:)`
|
22
|
+
# When raised, the initial subscription or update fails completely.
|
23
|
+
class SubscriptionScopeMissingError < GraphQL::Error
|
24
|
+
end
|
25
|
+
|
26
|
+
# @see {Subscriptions#initialize} for options, concrete implementations may add options.
|
27
|
+
def self.use(defn, options = {})
|
28
|
+
schema = defn.is_a?(Class) ? defn : defn.target
|
29
|
+
|
30
|
+
if schema.subscriptions
|
31
|
+
raise ArgumentError, "Can't reinstall subscriptions. #{schema} is using #{schema.subscriptions}, can't also add #{self}"
|
32
|
+
end
|
33
|
+
|
34
|
+
instrumentation = Subscriptions::Instrumentation.new(schema: schema)
|
35
|
+
defn.instrument(:query, instrumentation)
|
36
|
+
if !schema.is_a?(Class)
|
37
|
+
defn.instrument(:field, instrumentation)
|
38
|
+
end
|
39
|
+
options[:schema] = schema
|
40
|
+
schema.subscriptions = self.new(**options)
|
41
|
+
schema.add_subscription_extension_if_necessary
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param schema [Class] the GraphQL schema this manager belongs to
|
46
|
+
def initialize(schema:, broadcast: false, default_broadcastable: false, **rest)
|
47
|
+
if broadcast
|
48
|
+
if !schema.using_ast_analysis?
|
49
|
+
raise ArgumentError, "`broadcast: true` requires AST analysis, add `using GraphQL::Analysis::AST` to your schema or see https://graphql-ruby.org/queries/ast_analysis.html."
|
50
|
+
end
|
51
|
+
schema.query_analyzer(Subscriptions::BroadcastAnalyzer)
|
52
|
+
end
|
53
|
+
@default_broadcastable = default_broadcastable
|
54
|
+
@schema = schema
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Boolean] Used when fields don't have `broadcastable:` explicitly set
|
58
|
+
attr_reader :default_broadcastable
|
59
|
+
|
60
|
+
# Fetch subscriptions matching this field + arguments pair
|
61
|
+
# And pass them off to the queue.
|
62
|
+
# @param event_name [String]
|
63
|
+
# @param args [Hash<String, Symbol => Object]
|
64
|
+
# @param object [Object]
|
65
|
+
# @param scope [Symbol, String]
|
66
|
+
# @return [void]
|
67
|
+
def trigger(event_name, args, object, scope: nil)
|
68
|
+
event_name = event_name.to_s
|
69
|
+
|
70
|
+
# Try with the verbatim input first:
|
71
|
+
field = @schema.get_field(@schema.subscription, event_name)
|
72
|
+
|
73
|
+
if field.nil?
|
74
|
+
# And if it wasn't found, normalize it:
|
75
|
+
normalized_event_name = normalize_name(event_name)
|
76
|
+
field = @schema.get_field(@schema.subscription, normalized_event_name)
|
77
|
+
if field.nil?
|
78
|
+
raise InvalidTriggerError, "No subscription matching trigger: #{event_name} (looked for #{@schema.subscription.graphql_name}.#{normalized_event_name})"
|
79
|
+
end
|
80
|
+
else
|
81
|
+
# Since we found a field, the original input was already normalized
|
82
|
+
normalized_event_name = event_name
|
83
|
+
end
|
84
|
+
|
85
|
+
# Normalize symbol-keyed args to strings, try camelizing them
|
86
|
+
# Should this accept a real context somehow?
|
87
|
+
normalized_args = normalize_arguments(normalized_event_name, field, args, GraphQL::Query::NullContext)
|
88
|
+
|
89
|
+
event = Subscriptions::Event.new(
|
90
|
+
name: normalized_event_name,
|
91
|
+
arguments: normalized_args,
|
92
|
+
field: field,
|
93
|
+
scope: scope,
|
94
|
+
)
|
95
|
+
execute_all(event, object)
|
96
|
+
end
|
97
|
+
|
98
|
+
# `event` was triggered on `object`, and `subscription_id` was subscribed,
|
99
|
+
# so it should be updated.
|
100
|
+
#
|
101
|
+
# Load `subscription_id`'s GraphQL data, re-evaluate the query and return the result.
|
102
|
+
#
|
103
|
+
# @param subscription_id [String]
|
104
|
+
# @param event [GraphQL::Subscriptions::Event] The event which was triggered
|
105
|
+
# @param object [Object] The value for the subscription field
|
106
|
+
# @return [GraphQL::Query::Result]
|
107
|
+
def execute_update(subscription_id, event, object)
|
108
|
+
# Lookup the saved data for this subscription
|
109
|
+
query_data = read_subscription(subscription_id)
|
110
|
+
if query_data.nil?
|
111
|
+
delete_subscription(subscription_id)
|
112
|
+
return nil
|
113
|
+
end
|
114
|
+
|
115
|
+
# Fetch the required keys from the saved data
|
116
|
+
query_string = query_data.fetch(:query_string)
|
117
|
+
variables = query_data.fetch(:variables)
|
118
|
+
context = query_data.fetch(:context)
|
119
|
+
operation_name = query_data.fetch(:operation_name)
|
120
|
+
result = @schema.execute(
|
121
|
+
query: query_string,
|
122
|
+
context: context,
|
123
|
+
subscription_topic: event.topic,
|
124
|
+
operation_name: operation_name,
|
125
|
+
variables: variables,
|
126
|
+
root_value: object,
|
127
|
+
)
|
128
|
+
subscriptions_context = result.context.namespace(:subscriptions)
|
129
|
+
if subscriptions_context[:no_update]
|
130
|
+
result = nil
|
131
|
+
end
|
132
|
+
|
133
|
+
unsubscribed = subscriptions_context[:unsubscribed]
|
134
|
+
|
135
|
+
if unsubscribed
|
136
|
+
# `unsubscribe` was called, clean up on our side
|
137
|
+
# TODO also send `{more: false}` to client?
|
138
|
+
delete_subscription(subscription_id)
|
139
|
+
result = nil
|
140
|
+
end
|
141
|
+
|
142
|
+
result
|
143
|
+
end
|
144
|
+
|
145
|
+
# Run the update query for this subscription and deliver it
|
146
|
+
# @see {#execute_update}
|
147
|
+
# @see {#deliver}
|
148
|
+
# @return [void]
|
149
|
+
def execute(subscription_id, event, object)
|
150
|
+
res = execute_update(subscription_id, event, object)
|
151
|
+
if !res.nil?
|
152
|
+
deliver(subscription_id, res)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Event `event` occurred on `object`,
|
157
|
+
# Update all subscribers.
|
158
|
+
# @param event [Subscriptions::Event]
|
159
|
+
# @param object [Object]
|
160
|
+
# @return [void]
|
161
|
+
def execute_all(event, object)
|
162
|
+
raise GraphQL::RequiredImplementationMissingError
|
163
|
+
end
|
164
|
+
|
165
|
+
# The system wants to send an update to this subscription.
|
166
|
+
# Read its data and return it.
|
167
|
+
# @param subscription_id [String]
|
168
|
+
# @return [Hash] Containing required keys
|
169
|
+
def read_subscription(subscription_id)
|
170
|
+
raise GraphQL::RequiredImplementationMissingError
|
171
|
+
end
|
172
|
+
|
173
|
+
# A subscription query was re-evaluated, returning `result`.
|
174
|
+
# The result should be send to `subscription_id`.
|
175
|
+
# @param subscription_id [String]
|
176
|
+
# @param result [Hash]
|
177
|
+
# @return [void]
|
178
|
+
def deliver(subscription_id, result)
|
179
|
+
raise GraphQL::RequiredImplementationMissingError
|
180
|
+
end
|
181
|
+
|
182
|
+
# `query` was executed and found subscriptions to `events`.
|
183
|
+
# Update the database to reflect this new state.
|
184
|
+
# @param query [GraphQL::Query]
|
185
|
+
# @param events [Array<GraphQL::Subscriptions::Event>]
|
186
|
+
# @return [void]
|
187
|
+
def write_subscription(query, events)
|
188
|
+
raise GraphQL::RequiredImplementationMissingError
|
189
|
+
end
|
190
|
+
|
191
|
+
# A subscription was terminated server-side.
|
192
|
+
# Clean up the database.
|
193
|
+
# @param subscription_id [String]
|
194
|
+
# @return void.
|
195
|
+
def delete_subscription(subscription_id)
|
196
|
+
raise GraphQL::RequiredImplementationMissingError
|
197
|
+
end
|
198
|
+
|
199
|
+
# @return [String] A new unique identifier for a subscription
|
200
|
+
def build_id
|
201
|
+
SecureRandom.uuid
|
202
|
+
end
|
203
|
+
|
204
|
+
# Convert a user-provided event name or argument
|
205
|
+
# to the equivalent in GraphQL.
|
206
|
+
#
|
207
|
+
# By default, it converts the identifier to camelcase.
|
208
|
+
# Override this in a subclass to change the transformation.
|
209
|
+
#
|
210
|
+
# @param event_or_arg_name [String, Symbol]
|
211
|
+
# @return [String]
|
212
|
+
def normalize_name(event_or_arg_name)
|
213
|
+
Schema::Member::BuildType.camelize(event_or_arg_name.to_s)
|
214
|
+
end
|
215
|
+
|
216
|
+
# @return [Boolean] if true, then a query like this one would be broadcasted
|
217
|
+
def broadcastable?(query_str, **query_options)
|
218
|
+
query = GraphQL::Query.new(@schema, query_str, **query_options)
|
219
|
+
if !query.valid?
|
220
|
+
raise "Invalid query: #{query.validation_errors.map(&:to_h).inspect}"
|
221
|
+
end
|
222
|
+
GraphQL::Analysis::AST.analyze_query(query, @schema.query_analyzers)
|
223
|
+
query.context.namespace(:subscriptions)[:subscription_broadcastable]
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
# Recursively normalize `args` as belonging to `arg_owner`:
|
229
|
+
# - convert symbols to strings,
|
230
|
+
# - if needed, camelize the string (using {#normalize_name})
|
231
|
+
# @param arg_owner [GraphQL::Field, GraphQL::BaseType]
|
232
|
+
# @param args [Hash, Array, Any] some GraphQL input value to coerce as `arg_owner`
|
233
|
+
# @return [Any] normalized arguments value
|
234
|
+
def normalize_arguments(event_name, arg_owner, args, context)
|
235
|
+
case arg_owner
|
236
|
+
when GraphQL::Field, GraphQL::InputObjectType, GraphQL::Schema::Field, Class
|
237
|
+
if arg_owner.is_a?(Class) && !arg_owner.kind.input_object?
|
238
|
+
# it's a type, but not an input object
|
239
|
+
return args
|
240
|
+
end
|
241
|
+
normalized_args = {}
|
242
|
+
missing_arg_names = []
|
243
|
+
args.each do |k, v|
|
244
|
+
arg_name = k.to_s
|
245
|
+
arg_defn = arg_owner.get_argument(arg_name, context)
|
246
|
+
if arg_defn
|
247
|
+
normalized_arg_name = arg_name
|
248
|
+
else
|
249
|
+
normalized_arg_name = normalize_name(arg_name)
|
250
|
+
arg_defn = arg_owner.get_argument(normalized_arg_name, context)
|
251
|
+
end
|
252
|
+
|
253
|
+
if arg_defn
|
254
|
+
if arg_defn.loads
|
255
|
+
normalized_arg_name = arg_defn.keyword.to_s
|
256
|
+
end
|
257
|
+
normalized = normalize_arguments(event_name, arg_defn.type, v, context)
|
258
|
+
normalized_args[normalized_arg_name] = normalized
|
259
|
+
else
|
260
|
+
# Couldn't find a matching argument definition
|
261
|
+
missing_arg_names << arg_name
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Backfill default values so that trigger arguments
|
266
|
+
# match query arguments.
|
267
|
+
arg_owner.arguments(context).each do |_name, arg_defn|
|
268
|
+
if arg_defn.default_value? && !normalized_args.key?(arg_defn.name)
|
269
|
+
default_value = arg_defn.default_value
|
270
|
+
# We don't have an underlying "object" here, so it can't call methods.
|
271
|
+
# This is broken.
|
272
|
+
normalized_args[arg_defn.name] = arg_defn.prepare_value(nil, default_value, context: context)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
if missing_arg_names.any?
|
277
|
+
arg_owner_name = if arg_owner.is_a?(GraphQL::Field)
|
278
|
+
"Subscription.#{arg_owner.name}"
|
279
|
+
elsif arg_owner.is_a?(GraphQL::Schema::Field)
|
280
|
+
arg_owner.path
|
281
|
+
elsif arg_owner.is_a?(Class)
|
282
|
+
arg_owner.graphql_name
|
283
|
+
else
|
284
|
+
arg_owner.to_s
|
285
|
+
end
|
286
|
+
raise InvalidTriggerError, "Can't trigger Subscription.#{event_name}, received undefined arguments: #{missing_arg_names.join(", ")}. (Should match arguments of #{arg_owner_name}.)"
|
287
|
+
end
|
288
|
+
|
289
|
+
normalized_args
|
290
|
+
when GraphQL::ListType, GraphQL::Schema::List
|
291
|
+
args.map { |a| normalize_arguments(event_name, arg_owner.of_type, a, context) }
|
292
|
+
when GraphQL::NonNullType, GraphQL::Schema::NonNull
|
293
|
+
normalize_arguments(event_name, arg_owner.of_type, args, context)
|
294
|
+
else
|
295
|
+
args
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Tracing
|
5
|
+
# This implementation forwards events to ActiveSupport::Notifications
|
6
|
+
# with a `graphql` suffix.
|
7
|
+
#
|
8
|
+
# @see KEYS for event names
|
9
|
+
module ActiveSupportNotificationsTracing
|
10
|
+
# A cache of frequently-used keys to avoid needless string allocations
|
11
|
+
KEYS = {
|
12
|
+
"lex" => "lex.graphql",
|
13
|
+
"parse" => "parse.graphql",
|
14
|
+
"validate" => "validate.graphql",
|
15
|
+
"analyze_multiplex" => "analyze_multiplex.graphql",
|
16
|
+
"analyze_query" => "analyze_query.graphql",
|
17
|
+
"execute_query" => "execute_query.graphql",
|
18
|
+
"execute_query_lazy" => "execute_query_lazy.graphql",
|
19
|
+
"execute_field" => "execute_field.graphql",
|
20
|
+
"execute_field_lazy" => "execute_field_lazy.graphql",
|
21
|
+
"authorized" => "authorized.graphql",
|
22
|
+
"authorized_lazy" => "authorized_lazy.graphql",
|
23
|
+
"resolve_type" => "resolve_type.graphql",
|
24
|
+
"resolve_type_lazy" => "resolve_type.graphql",
|
25
|
+
}
|
26
|
+
|
27
|
+
def self.trace(key, metadata)
|
28
|
+
prefixed_key = KEYS[key] || "#{key}.graphql"
|
29
|
+
ActiveSupport::Notifications.instrument(prefixed_key, metadata) do
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|