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,383 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Argument
|
5
|
+
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
6
|
+
include GraphQL::Schema::Member::AcceptsDefinition
|
7
|
+
include GraphQL::Schema::Member::HasPath
|
8
|
+
include GraphQL::Schema::Member::HasAstNode
|
9
|
+
include GraphQL::Schema::Member::HasDirectives
|
10
|
+
include GraphQL::Schema::Member::HasDeprecationReason
|
11
|
+
include GraphQL::Schema::Member::HasValidators
|
12
|
+
include GraphQL::Schema::FindInheritedValue::EmptyObjects
|
13
|
+
|
14
|
+
NO_DEFAULT = :__no_default__
|
15
|
+
|
16
|
+
# @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
|
17
|
+
attr_reader :name
|
18
|
+
alias :graphql_name :name
|
19
|
+
|
20
|
+
# @return [GraphQL::Schema::Field, Class] The field or input object this argument belongs to
|
21
|
+
attr_reader :owner
|
22
|
+
|
23
|
+
# @return [Symbol] A method to call to transform this value before sending it to field resolution method
|
24
|
+
attr_reader :prepare
|
25
|
+
|
26
|
+
# @return [Symbol] This argument's name in Ruby keyword arguments
|
27
|
+
attr_reader :keyword
|
28
|
+
|
29
|
+
# @return [Class, Module, nil] If this argument should load an application object, this is the type of object to load
|
30
|
+
attr_reader :loads
|
31
|
+
|
32
|
+
# @return [Boolean] true if a resolver defined this argument
|
33
|
+
def from_resolver?
|
34
|
+
@from_resolver
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param arg_name [Symbol]
|
38
|
+
# @param type_expr
|
39
|
+
# @param desc [String]
|
40
|
+
# @param required [Boolean] if true, this argument is non-null; if false, this argument is nullable
|
41
|
+
# @param description [String]
|
42
|
+
# @param default_value [Object]
|
43
|
+
# @param as [Symbol] Override the keyword name when passed to a method
|
44
|
+
# @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
|
45
|
+
# @param camelize [Boolean] if true, the name will be camelized when building the schema
|
46
|
+
# @param from_resolver [Boolean] if true, a Resolver class defined this argument
|
47
|
+
# @param method_access [Boolean] If false, don't build method access on legacy {Query::Arguments} instances.
|
48
|
+
# @param directives [Hash{Class => Hash}]
|
49
|
+
# @param deprecation_reason [String]
|
50
|
+
# @param validates [Hash, nil] Options for building validators, if any should be applied
|
51
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, method_access: true, owner:, validates: nil, directives: nil, deprecation_reason: nil, &definition_block)
|
52
|
+
arg_name ||= name
|
53
|
+
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
54
|
+
@type_expr = type_expr || type
|
55
|
+
@description = desc || description
|
56
|
+
@null = !required
|
57
|
+
@default_value = default_value
|
58
|
+
@owner = owner
|
59
|
+
@as = as
|
60
|
+
@loads = loads
|
61
|
+
@keyword = as || (arg_name.is_a?(Symbol) ? arg_name : Schema::Member::BuildType.underscore(@name).to_sym)
|
62
|
+
@prepare = prepare
|
63
|
+
@ast_node = ast_node
|
64
|
+
@from_resolver = from_resolver
|
65
|
+
@method_access = method_access
|
66
|
+
self.deprecation_reason = deprecation_reason
|
67
|
+
|
68
|
+
if directives
|
69
|
+
directives.each do |dir_class, dir_options|
|
70
|
+
directive(dir_class, **dir_options)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
self.validates(validates)
|
75
|
+
|
76
|
+
if definition_block
|
77
|
+
if definition_block.arity == 1
|
78
|
+
instance_exec(self, &definition_block)
|
79
|
+
else
|
80
|
+
instance_eval(&definition_block)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def inspect
|
86
|
+
"#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>"
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [Object] the value used when the client doesn't provide a value for this argument
|
90
|
+
attr_reader :default_value
|
91
|
+
|
92
|
+
# @return [Boolean] True if this argument has a default value
|
93
|
+
def default_value?
|
94
|
+
@default_value != NO_DEFAULT
|
95
|
+
end
|
96
|
+
|
97
|
+
attr_writer :description
|
98
|
+
|
99
|
+
# @return [String] Documentation for this argument
|
100
|
+
def description(text = nil)
|
101
|
+
if text
|
102
|
+
@description = text
|
103
|
+
else
|
104
|
+
@description
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @return [String] Deprecation reason for this argument
|
109
|
+
def deprecation_reason(text = nil)
|
110
|
+
if text
|
111
|
+
self.deprecation_reason = text
|
112
|
+
else
|
113
|
+
super()
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def deprecation_reason=(new_reason)
|
118
|
+
validate_deprecated_or_optional(null: @null, deprecation_reason: new_reason)
|
119
|
+
super
|
120
|
+
end
|
121
|
+
|
122
|
+
def visible?(context)
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
def accessible?(context)
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
def authorized?(obj, value, ctx)
|
131
|
+
authorized_as_type?(obj, value, ctx, as_type: type)
|
132
|
+
end
|
133
|
+
|
134
|
+
def authorized_as_type?(obj, value, ctx, as_type:)
|
135
|
+
if value.nil?
|
136
|
+
return true
|
137
|
+
end
|
138
|
+
|
139
|
+
if as_type.kind.non_null?
|
140
|
+
as_type = as_type.of_type
|
141
|
+
end
|
142
|
+
|
143
|
+
if as_type.kind.list?
|
144
|
+
value.each do |v|
|
145
|
+
if !authorized_as_type?(obj, v, ctx, as_type: as_type.of_type)
|
146
|
+
return false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
elsif as_type.kind.input_object?
|
150
|
+
as_type.arguments(ctx).each do |_name, input_obj_arg|
|
151
|
+
input_obj_arg = input_obj_arg.type_class
|
152
|
+
# TODO: this skips input objects whose values were alread replaced with application objects.
|
153
|
+
# See: https://github.com/rmosolgo/graphql-ruby/issues/2633
|
154
|
+
if value.is_a?(InputObject) && value.key?(input_obj_arg.keyword) && !input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
|
155
|
+
return false
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
# None of the early-return conditions were activated,
|
160
|
+
# so this is authorized.
|
161
|
+
true
|
162
|
+
end
|
163
|
+
|
164
|
+
def to_graphql
|
165
|
+
argument = GraphQL::Argument.new
|
166
|
+
argument.name = @name
|
167
|
+
argument.type = -> { type }
|
168
|
+
argument.description = @description
|
169
|
+
argument.metadata[:type_class] = self
|
170
|
+
argument.as = @as
|
171
|
+
argument.ast_node = ast_node
|
172
|
+
argument.method_access = @method_access
|
173
|
+
if NO_DEFAULT != @default_value
|
174
|
+
argument.default_value = @default_value
|
175
|
+
end
|
176
|
+
if self.deprecation_reason
|
177
|
+
argument.deprecation_reason = self.deprecation_reason
|
178
|
+
end
|
179
|
+
argument
|
180
|
+
end
|
181
|
+
|
182
|
+
def type=(new_type)
|
183
|
+
validate_input_type(new_type)
|
184
|
+
# This isn't true for LateBoundTypes, but we can assume those will
|
185
|
+
# be updated via this codepath later in schema setup.
|
186
|
+
if new_type.respond_to?(:non_null?)
|
187
|
+
validate_deprecated_or_optional(null: !new_type.non_null?, deprecation_reason: deprecation_reason)
|
188
|
+
end
|
189
|
+
@type = new_type
|
190
|
+
end
|
191
|
+
|
192
|
+
def type
|
193
|
+
@type ||= begin
|
194
|
+
parsed_type = begin
|
195
|
+
Member::BuildType.parse_type(@type_expr, null: @null)
|
196
|
+
rescue StandardError => err
|
197
|
+
raise ArgumentError, "Couldn't build type for Argument #{@owner.name}.#{name}: #{err.class.name}: #{err.message}", err.backtrace
|
198
|
+
end
|
199
|
+
# Use the setter method to get validations
|
200
|
+
self.type = parsed_type
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def statically_coercible?
|
205
|
+
return @statically_coercible if defined?(@statically_coercible)
|
206
|
+
|
207
|
+
@statically_coercible = !@prepare.is_a?(String) && !@prepare.is_a?(Symbol)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Apply the {prepare} configuration to `value`, using methods from `obj`.
|
211
|
+
# Used by the runtime.
|
212
|
+
# @api private
|
213
|
+
def prepare_value(obj, value, context: nil)
|
214
|
+
if value.is_a?(GraphQL::Schema::InputObject)
|
215
|
+
value = value.prepare
|
216
|
+
end
|
217
|
+
|
218
|
+
Schema::Validator.validate!(validators, obj, context, value)
|
219
|
+
|
220
|
+
if @prepare.nil?
|
221
|
+
value
|
222
|
+
elsif @prepare.is_a?(String) || @prepare.is_a?(Symbol)
|
223
|
+
if obj.nil?
|
224
|
+
# The problem here is, we _used to_ prepare while building variables.
|
225
|
+
# But now we don't have the runtime object there.
|
226
|
+
#
|
227
|
+
# This will have to be called later, when the runtime object _is_ available.
|
228
|
+
value
|
229
|
+
else
|
230
|
+
obj.public_send(@prepare, value)
|
231
|
+
end
|
232
|
+
elsif @prepare.respond_to?(:call)
|
233
|
+
@prepare.call(value, context || obj.context)
|
234
|
+
else
|
235
|
+
raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# @api private
|
240
|
+
def coerce_into_values(parent_object, values, context, argument_values)
|
241
|
+
arg_name = graphql_name
|
242
|
+
arg_key = keyword
|
243
|
+
default_used = false
|
244
|
+
|
245
|
+
if values.key?(arg_name)
|
246
|
+
value = values[arg_name]
|
247
|
+
elsif values.key?(arg_key)
|
248
|
+
value = values[arg_key]
|
249
|
+
elsif default_value?
|
250
|
+
value = default_value
|
251
|
+
default_used = true
|
252
|
+
else
|
253
|
+
# no value at all
|
254
|
+
owner.validate_directive_argument(self, nil)
|
255
|
+
return
|
256
|
+
end
|
257
|
+
|
258
|
+
loaded_value = nil
|
259
|
+
coerced_value = context.schema.error_handler.with_error_handling(context) do
|
260
|
+
type.coerce_input(value, context)
|
261
|
+
end
|
262
|
+
|
263
|
+
# If this isn't lazy, then the block returns eagerly and assigns the result here
|
264
|
+
# If it _is_ lazy, then we write the lazy to the hash, then update it later
|
265
|
+
argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |resolved_coerced_value|
|
266
|
+
if loads && !from_resolver?
|
267
|
+
loaded_value = context.query.with_error_handling do
|
268
|
+
load_and_authorize_value(owner, coerced_value, context)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
maybe_loaded_value = loaded_value || resolved_coerced_value
|
273
|
+
context.schema.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
|
274
|
+
owner.validate_directive_argument(self, resolved_loaded_value)
|
275
|
+
prepared_value = context.schema.error_handler.with_error_handling(context) do
|
276
|
+
prepare_value(parent_object, resolved_loaded_value, context: context)
|
277
|
+
end
|
278
|
+
|
279
|
+
# TODO code smell to access such a deeply-nested constant in a distant module
|
280
|
+
argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
|
281
|
+
value: prepared_value,
|
282
|
+
definition: self,
|
283
|
+
default_used: default_used,
|
284
|
+
)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def load_and_authorize_value(load_method_owner, coerced_value, context)
|
290
|
+
if coerced_value.nil?
|
291
|
+
return nil
|
292
|
+
end
|
293
|
+
arg_load_method = "load_#{keyword}"
|
294
|
+
if load_method_owner.respond_to?(arg_load_method)
|
295
|
+
custom_loaded_value = if load_method_owner.is_a?(Class)
|
296
|
+
load_method_owner.public_send(arg_load_method, coerced_value, context)
|
297
|
+
else
|
298
|
+
load_method_owner.public_send(arg_load_method, coerced_value)
|
299
|
+
end
|
300
|
+
context.schema.after_lazy(custom_loaded_value) do |custom_value|
|
301
|
+
if loads
|
302
|
+
if type.list?
|
303
|
+
loaded_values = custom_value.each_with_index.map { |custom_val, idx|
|
304
|
+
id = coerced_value[idx]
|
305
|
+
load_method_owner.authorize_application_object(self, id, context, custom_val)
|
306
|
+
}
|
307
|
+
context.schema.after_any_lazies(loaded_values, &:itself)
|
308
|
+
else
|
309
|
+
load_method_owner.authorize_application_object(self, coerced_value, context, custom_loaded_value)
|
310
|
+
end
|
311
|
+
else
|
312
|
+
custom_value
|
313
|
+
end
|
314
|
+
end
|
315
|
+
elsif loads
|
316
|
+
if type.list?
|
317
|
+
loaded_values = coerced_value.map { |val| load_method_owner.load_and_authorize_application_object(self, val, context) }
|
318
|
+
context.schema.after_any_lazies(loaded_values, &:itself)
|
319
|
+
else
|
320
|
+
load_method_owner.load_and_authorize_application_object(self, coerced_value, context)
|
321
|
+
end
|
322
|
+
else
|
323
|
+
coerced_value
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
# @api private
|
328
|
+
def validate_default_value
|
329
|
+
coerced_default_value = begin
|
330
|
+
# This is weird, but we should accept single-item default values for list-type arguments.
|
331
|
+
# If we used `coerce_isolated_input` below, it would do this for us, but it's not really
|
332
|
+
# the right thing here because we expect default values in application format (Ruby values)
|
333
|
+
# not GraphQL format (scalar values).
|
334
|
+
#
|
335
|
+
# But I don't think Schema::List#coerce_result should apply wrapping to single-item lists.
|
336
|
+
prepped_default_value = if default_value.nil?
|
337
|
+
nil
|
338
|
+
elsif (type.kind.list? || (type.kind.non_null? && type.of_type.list?)) && !default_value.respond_to?(:map)
|
339
|
+
[default_value]
|
340
|
+
else
|
341
|
+
default_value
|
342
|
+
end
|
343
|
+
|
344
|
+
type.coerce_isolated_result(prepped_default_value) unless prepped_default_value.nil?
|
345
|
+
rescue GraphQL::Schema::Enum::UnresolvedValueError
|
346
|
+
# It raises this, which is helpful at runtime, but not here...
|
347
|
+
default_value
|
348
|
+
end
|
349
|
+
res = type.valid_isolated_input?(coerced_default_value)
|
350
|
+
if !res
|
351
|
+
raise InvalidDefaultValueError.new(self)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
class InvalidDefaultValueError < GraphQL::Error
|
356
|
+
def initialize(argument)
|
357
|
+
message = "`#{argument.path}` has an invalid default value: `#{argument.default_value.inspect}` isn't accepted by `#{argument.type.to_type_signature}`; update the default value or the argument type."
|
358
|
+
super(message)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
private
|
363
|
+
|
364
|
+
def validate_input_type(input_type)
|
365
|
+
if input_type.is_a?(String) || input_type.is_a?(GraphQL::Schema::LateBoundType)
|
366
|
+
# Do nothing; assume this will be validated later
|
367
|
+
elsif input_type.kind.non_null? || input_type.kind.list?
|
368
|
+
validate_input_type(input_type.unwrap)
|
369
|
+
elsif !input_type.kind.input?
|
370
|
+
raise ArgumentError, "Invalid input type for #{path}: #{input_type.graphql_name}. Must be scalar, enum, or input object, not #{input_type.kind.name}."
|
371
|
+
else
|
372
|
+
# It's an input type, we're OK
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def validate_deprecated_or_optional(null:, deprecation_reason:)
|
377
|
+
if deprecation_reason && !null
|
378
|
+
raise ArgumentError, "Required arguments cannot be deprecated: #{path}."
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
# backport from ruby v2.5 to v2.2 that has no `padding` things
|
6
|
+
# @api private
|
7
|
+
module Base64Bp
|
8
|
+
extend Base64
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def urlsafe_encode64(bin, padding:)
|
13
|
+
str = strict_encode64(bin)
|
14
|
+
str.tr!("+/", "-_")
|
15
|
+
str.delete!("=") unless padding
|
16
|
+
str
|
17
|
+
end
|
18
|
+
|
19
|
+
def urlsafe_decode64(str)
|
20
|
+
str = str.tr("-_", "+/")
|
21
|
+
if !str.end_with?("=") && str.length % 4 != 0
|
22
|
+
str = str.ljust((str.length + 3) & ~3, "=")
|
23
|
+
end
|
24
|
+
strict_decode64(str)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql/schema/base_64_bp'
|
4
|
+
|
5
|
+
module GraphQL
|
6
|
+
class Schema
|
7
|
+
# @api private
|
8
|
+
module Base64Encoder
|
9
|
+
def self.encode(unencoded_text, nonce: false)
|
10
|
+
Base64Bp.urlsafe_encode64(unencoded_text, padding: false)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.decode(encoded_text, nonce: false)
|
14
|
+
# urlsafe_decode64 is for forward compatibility
|
15
|
+
Base64Bp.urlsafe_decode64(encoded_text)
|
16
|
+
rescue ArgumentError
|
17
|
+
raise GraphQL::ExecutionError, "Invalid input: #{encoded_text.inspect}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
module BuildFromDefinition
|
5
|
+
class ResolveMap
|
6
|
+
class DefaultResolve
|
7
|
+
def initialize(field_map, field_name)
|
8
|
+
@field_map = field_map
|
9
|
+
@field_name = field_name
|
10
|
+
end
|
11
|
+
|
12
|
+
# Make some runtime checks about
|
13
|
+
# how `obj` implements the `field_name`.
|
14
|
+
#
|
15
|
+
# Create a new resolve function according to that implementation, then:
|
16
|
+
# - update `field_map` with this implementation
|
17
|
+
# - call the implementation now (to satisfy this field execution)
|
18
|
+
#
|
19
|
+
# If `obj` doesn't implement `field_name`, raise an error.
|
20
|
+
def call(obj, args, ctx)
|
21
|
+
method_name = @field_name
|
22
|
+
if !obj.respond_to?(method_name)
|
23
|
+
raise KeyError, "Can't resolve field #{method_name} on #{obj.inspect}"
|
24
|
+
else
|
25
|
+
method_arity = obj.method(method_name).arity
|
26
|
+
resolver = case method_arity
|
27
|
+
when 0, -1
|
28
|
+
# -1 Handles method_missing, eg openstruct
|
29
|
+
->(o, a, c) { o.public_send(method_name) }
|
30
|
+
when 1
|
31
|
+
->(o, a, c) { o.public_send(method_name, a) }
|
32
|
+
when 2
|
33
|
+
->(o, a, c) { o.public_send(method_name, a, c) }
|
34
|
+
else
|
35
|
+
raise "Unexpected resolve arity: #{method_arity}. Must be 0, 1, 2"
|
36
|
+
end
|
37
|
+
# Call the resolver directly next time
|
38
|
+
@field_map[method_name] = resolver
|
39
|
+
# Call through this time
|
40
|
+
resolver.call(obj, args, ctx)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "graphql/schema/build_from_definition/resolve_map/default_resolve"
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
class Schema
|
6
|
+
module BuildFromDefinition
|
7
|
+
# Wrap a user-provided hash of resolution behavior for easy access at runtime.
|
8
|
+
#
|
9
|
+
# Coerce scalar values by:
|
10
|
+
# - Checking for a function in the map like `{ Date: { coerce_input: ->(val, ctx) { ... }, coerce_result: ->(val, ctx) { ... } } }`
|
11
|
+
# - Falling back to a passthrough
|
12
|
+
#
|
13
|
+
# Interface/union resolution can be provided as a `resolve_type:` key.
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
class ResolveMap
|
17
|
+
module NullScalarCoerce
|
18
|
+
def self.call(val, _ctx)
|
19
|
+
val
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(user_resolve_hash)
|
24
|
+
@resolve_hash = Hash.new do |h, k|
|
25
|
+
# For each type name, provide a new hash if one wasn't given:
|
26
|
+
h[k] = Hash.new do |h2, k2|
|
27
|
+
if k2 == "coerce_input" || k2 == "coerce_result"
|
28
|
+
# This isn't an object field, it's a scalar coerce function.
|
29
|
+
# Use a passthrough
|
30
|
+
NullScalarCoerce
|
31
|
+
else
|
32
|
+
# For each field, provide a resolver that will
|
33
|
+
# make runtime checks & replace itself
|
34
|
+
h2[k2] = DefaultResolve.new(h2, k2)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@user_resolve_hash = user_resolve_hash
|
39
|
+
# User-provided resolve functions take priority over the default:
|
40
|
+
@user_resolve_hash.each do |type_name, fields|
|
41
|
+
type_name_s = type_name.to_s
|
42
|
+
case fields
|
43
|
+
when Hash
|
44
|
+
fields.each do |field_name, resolve_fn|
|
45
|
+
@resolve_hash[type_name_s][field_name.to_s] = resolve_fn
|
46
|
+
end
|
47
|
+
when Proc
|
48
|
+
# for example, "resolve_type"
|
49
|
+
@resolve_hash[type_name_s] = fields
|
50
|
+
else
|
51
|
+
raise ArgumentError, "Unexpected resolve hash value for #{type_name.inspect}: #{fields.inspect} (#{fields.class})"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Check the normalized hash, not the user input:
|
56
|
+
if @resolve_hash.key?("resolve_type")
|
57
|
+
define_singleton_method :resolve_type do |type, obj, ctx|
|
58
|
+
@resolve_hash.fetch("resolve_type").call(type, obj, ctx)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def call(type, field, obj, args, ctx)
|
64
|
+
resolver = @resolve_hash[type.graphql_name][field.graphql_name]
|
65
|
+
resolver.call(obj, args, ctx)
|
66
|
+
end
|
67
|
+
|
68
|
+
def coerce_input(type, value, ctx)
|
69
|
+
@resolve_hash[type.graphql_name]["coerce_input"].call(value, ctx)
|
70
|
+
end
|
71
|
+
|
72
|
+
def coerce_result(type, value, ctx)
|
73
|
+
@resolve_hash[type.graphql_name]["coerce_result"].call(value, ctx)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|