graphql 1.10.2 → 2.0.21
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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +45 -8
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +49 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -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 +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +24 -33
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +30 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +125 -117
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +52 -36
- data/lib/graphql/analysis/ast.rb +7 -8
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +31 -18
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +26 -18
- data/lib/graphql/dataloader/null_dataloader.rb +24 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +164 -0
- data/lib/graphql/dataloader.rb +311 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +77 -44
- 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 +104 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +62 -24
- data/lib/graphql/execution/interpreter/runtime.rb +826 -464
- data/lib/graphql/execution/interpreter.rb +206 -68
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +55 -136
- data/lib/graphql/execution/multiplex.rb +6 -162
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +7 -2
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +11 -5
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +4 -17
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +11 -6
- data/lib/graphql/introspection/type_type.rb +31 -14
- data/lib/graphql/introspection.rb +100 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +96 -44
- data/lib/graphql/language/lexer.rb +216 -1462
- data/lib/graphql/language/nodes.rb +126 -129
- data/lib/graphql/language/parser.rb +997 -933
- data/lib/graphql/language/parser.y +148 -118
- data/lib/graphql/language/printer.rb +48 -23
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +192 -84
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +45 -3
- data/lib/graphql/pagination/array_connection.rb +6 -4
- data/lib/graphql/pagination/connection.rb +105 -23
- data/lib/graphql/pagination/connections.rb +62 -35
- data/lib/graphql/pagination/relation_connection.rb +88 -36
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +203 -198
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +33 -7
- data/lib/graphql/query/null_context.rb +22 -9
- data/lib/graphql/query/validation_pipeline.rb +16 -38
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +36 -12
- data/lib/graphql/query.rb +92 -44
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +41 -10
- data/lib/graphql/relay/range_add.rb +17 -10
- data/lib/graphql/relay.rb +0 -15
- 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/schema/addition.rb +245 -0
- data/lib/graphql/schema/argument.rb +250 -46
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +243 -89
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +108 -20
- data/lib/graphql/schema/enum.rb +105 -44
- data/lib/graphql/schema/enum_value.rb +15 -25
- data/lib/graphql/schema/field/connection_extension.rb +50 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +476 -331
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +6 -8
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +133 -121
- data/lib/graphql/schema/interface.rb +17 -45
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +25 -8
- data/lib/graphql/schema/loader.rb +139 -103
- data/lib/graphql/schema/member/base_dsl_methods.rb +29 -35
- data/lib/graphql/schema/member/build_type.rb +19 -14
- data/lib/graphql/schema/member/has_arguments.rb +310 -26
- data/lib/graphql/schema/member/has_ast_node.rb +16 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
- data/lib/graphql/schema/member/has_directives.rb +118 -0
- data/lib/graphql/schema/member/has_fields.rb +164 -42
- data/lib/graphql/schema/member/has_interfaces.rb +129 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +57 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +12 -7
- data/lib/graphql/schema/object.rb +35 -69
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
- data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
- data/lib/graphql/schema/resolver.rb +144 -79
- data/lib/graphql/schema/scalar.rb +27 -18
- data/lib/graphql/schema/subscription.rb +55 -26
- data/lib/graphql/schema/timeout.rb +45 -35
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +21 -4
- data/lib/graphql/schema/union.rb +48 -13
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- 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 +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +185 -32
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +471 -1116
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +13 -27
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +69 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +92 -49
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- 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/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +32 -20
- data/lib/graphql/static_validation.rb +1 -2
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +126 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +81 -35
- data/lib/graphql/subscriptions/instrumentation.rb +0 -52
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +113 -58
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +26 -2
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +64 -43
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +23 -71
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +20 -9
- data/lib/graphql/types/iso_8601_date_time.rb +36 -10
- data/lib/graphql/types/relay/base_connection.rb +18 -92
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +75 -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 +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +25 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
- data/lib/graphql/types/relay.rb +10 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +54 -65
- data/readme.md +3 -6
- metadata +116 -236
- data/lib/graphql/analysis/analyze_query.rb +0 -91
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -230
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -435
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -210
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -42
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -127
- data/lib/graphql/execution/execute.rb +0 -326
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -222
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -124
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -132
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -65
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -258
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -121
- data/lib/graphql/query/arguments.rb +0 -188
- data/lib/graphql/query/arguments_cache.rb +0 -25
- data/lib/graphql/query/executor.rb +0 -53
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -39
- data/lib/graphql/relay/array_connection.rb +0 -85
- data/lib/graphql/relay/base_connection.rb +0 -176
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -41
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -105
- data/lib/graphql/relay/node.rb +0 -36
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -76
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -15
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
- data/lib/graphql/schema/member/instrumentation.rb +0 -132
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -39
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -86
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -303
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -65
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
- data/lib/graphql/types/relay/node_field.rb +0 -43
- data/lib/graphql/types/relay/nodes_field.rb +0 -45
- data/lib/graphql/union_type.rb +0 -113
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
data/lib/graphql/language.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/language/block_string"
|
3
3
|
require "graphql/language/printer"
|
4
|
+
require "graphql/language/sanitized_printer"
|
4
5
|
require "graphql/language/document_from_schema_definition"
|
5
6
|
require "graphql/language/generation"
|
6
7
|
require "graphql/language/lexer"
|
7
8
|
require "graphql/language/nodes"
|
9
|
+
require "graphql/language/cache"
|
8
10
|
require "graphql/language/parser"
|
9
11
|
require "graphql/language/token"
|
10
12
|
require "graphql/language/visitor"
|
@@ -4,13 +4,8 @@ module GraphQL
|
|
4
4
|
VALID_NAME_REGEX = /^[_a-zA-Z][_a-zA-Z0-9]*$/
|
5
5
|
|
6
6
|
def self.validate!(name)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def self.valid?(name)
|
13
|
-
name =~ VALID_NAME_REGEX
|
7
|
+
name = name.is_a?(String) ? name : name.to_s
|
8
|
+
raise GraphQL::InvalidNameError.new(name, VALID_NAME_REGEX) unless name.match?(VALID_NAME_REGEX)
|
14
9
|
end
|
15
10
|
end
|
16
11
|
end
|
@@ -5,21 +5,39 @@ module GraphQL
|
|
5
5
|
module Pagination
|
6
6
|
# Customizes `RelationConnection` to work with `ActiveRecord::Relation`s.
|
7
7
|
class ActiveRecordRelationConnection < Pagination::RelationConnection
|
8
|
+
private
|
9
|
+
|
8
10
|
def relation_count(relation)
|
9
|
-
if
|
11
|
+
int_or_hash = if already_loaded?(relation)
|
12
|
+
relation.size
|
13
|
+
elsif relation.respond_to?(:unscope)
|
10
14
|
relation.unscope(:order).count(:all)
|
11
15
|
else
|
12
16
|
# Rails 3
|
13
17
|
relation.count
|
14
18
|
end
|
19
|
+
if int_or_hash.is_a?(Integer)
|
20
|
+
int_or_hash
|
21
|
+
else
|
22
|
+
# Grouped relations return count-by-group hashes
|
23
|
+
int_or_hash.length
|
24
|
+
end
|
15
25
|
end
|
16
26
|
|
17
27
|
def relation_limit(relation)
|
18
|
-
relation.
|
28
|
+
if relation.is_a?(Array)
|
29
|
+
nil
|
30
|
+
else
|
31
|
+
relation.limit_value
|
32
|
+
end
|
19
33
|
end
|
20
34
|
|
21
35
|
def relation_offset(relation)
|
22
|
-
relation.
|
36
|
+
if relation.is_a?(Array)
|
37
|
+
nil
|
38
|
+
else
|
39
|
+
relation.offset_value
|
40
|
+
end
|
23
41
|
end
|
24
42
|
|
25
43
|
def null_relation(relation)
|
@@ -30,6 +48,30 @@ module GraphQL
|
|
30
48
|
relation.where("1=2")
|
31
49
|
end
|
32
50
|
end
|
51
|
+
|
52
|
+
def set_limit(nodes, limit)
|
53
|
+
if already_loaded?(nodes)
|
54
|
+
nodes.take(limit)
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_offset(nodes, offset)
|
61
|
+
if already_loaded?(nodes)
|
62
|
+
# If the client sent a bogus cursor beyond the size of the relation,
|
63
|
+
# it might get `nil` from `#[...]`, so return an empty array in that case
|
64
|
+
nodes[offset..-1] || []
|
65
|
+
else
|
66
|
+
super
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def already_loaded?(relation)
|
73
|
+
relation.is_a?(Array) || relation.loaded?
|
74
|
+
end
|
33
75
|
end
|
34
76
|
end
|
35
77
|
end
|
@@ -21,7 +21,7 @@ module GraphQL
|
|
21
21
|
|
22
22
|
def cursor_for(item)
|
23
23
|
idx = items.find_index(item) + 1
|
24
|
-
|
24
|
+
encode(idx.to_s)
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
@@ -35,9 +35,11 @@ module GraphQL
|
|
35
35
|
def load_nodes
|
36
36
|
@nodes ||= begin
|
37
37
|
sliced_nodes = if before && after
|
38
|
-
|
38
|
+
end_idx = index_from_cursor(before)-1
|
39
|
+
end_idx < 0 ? [] : items[index_from_cursor(after)..end_idx] || []
|
39
40
|
elsif before
|
40
|
-
|
41
|
+
end_idx = index_from_cursor(before)-2
|
42
|
+
end_idx < 0 ? [] : items[0..end_idx] || []
|
41
43
|
elsif after
|
42
44
|
items[index_from_cursor(after)..-1] || []
|
43
45
|
else
|
@@ -59,7 +61,7 @@ module GraphQL
|
|
59
61
|
sliced_nodes.count > first
|
60
62
|
elsif before
|
61
63
|
# The original array is longer than the `before` index
|
62
|
-
index_from_cursor(before) < items.length
|
64
|
+
index_from_cursor(before) < items.length + 1
|
63
65
|
else
|
64
66
|
false
|
65
67
|
end
|
@@ -15,67 +15,137 @@ module GraphQL
|
|
15
15
|
class PaginationImplementationMissingError < GraphQL::Error
|
16
16
|
end
|
17
17
|
|
18
|
-
# @return [Class] The class to use for wrapping items as `edges { ... }`. Defaults to `Connection::Edge`
|
19
|
-
def self.edge_class
|
20
|
-
self::Edge
|
21
|
-
end
|
22
|
-
|
23
18
|
# @return [Object] A list object, from the application. This is the unpaginated value passed into the connection.
|
24
19
|
attr_reader :items
|
25
20
|
|
26
21
|
# @return [GraphQL::Query::Context]
|
27
22
|
attr_accessor :context
|
28
23
|
|
24
|
+
# @return [Object] the object this collection belongs to
|
25
|
+
attr_accessor :parent
|
26
|
+
|
29
27
|
# Raw access to client-provided values. (`max_page_size` not applied to first or last.)
|
30
28
|
attr_accessor :before_value, :after_value, :first_value, :last_value
|
31
29
|
|
32
|
-
# @return [String, nil] the client-provided cursor
|
30
|
+
# @return [String, nil] the client-provided cursor. `""` is treated as `nil`.
|
33
31
|
def before
|
34
|
-
@
|
32
|
+
if defined?(@before)
|
33
|
+
@before
|
34
|
+
else
|
35
|
+
@before = @before_value == "" ? nil : @before_value
|
36
|
+
end
|
35
37
|
end
|
36
38
|
|
37
|
-
# @return [String, nil] the client-provided cursor
|
39
|
+
# @return [String, nil] the client-provided cursor. `""` is treated as `nil`.
|
38
40
|
def after
|
39
|
-
@
|
41
|
+
if defined?(@after)
|
42
|
+
@after
|
43
|
+
else
|
44
|
+
@after = @after_value == "" ? nil : @after_value
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
48
|
+
# @return [Hash<Symbol => Object>] The field arguments from the field that returned this connection
|
49
|
+
attr_accessor :arguments
|
50
|
+
|
42
51
|
# @param items [Object] some unpaginated collection item, like an `Array` or `ActiveRecord::Relation`
|
43
52
|
# @param context [Query::Context]
|
53
|
+
# @param parent [Object] The object this collection belongs to
|
44
54
|
# @param first [Integer, nil] The limit parameter from the client, if it provided one
|
45
55
|
# @param after [String, nil] A cursor for pagination, if the client provided one
|
46
56
|
# @param last [Integer, nil] Limit parameter from the client, if provided
|
47
57
|
# @param before [String, nil] A cursor for pagination, if the client provided one.
|
48
|
-
# @param
|
49
|
-
|
58
|
+
# @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
|
59
|
+
# @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
|
60
|
+
# @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
|
61
|
+
def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil)
|
50
62
|
@items = items
|
63
|
+
@parent = parent
|
51
64
|
@context = context
|
65
|
+
@field = field
|
52
66
|
@first_value = first
|
53
67
|
@after_value = after
|
54
68
|
@last_value = last
|
55
69
|
@before_value = before
|
56
|
-
@
|
70
|
+
@arguments = arguments
|
71
|
+
@edge_class = edge_class || self.class::Edge
|
72
|
+
# This is only true if the object was _initialized_ with an override
|
73
|
+
# or if one is assigned later.
|
74
|
+
@has_max_page_size_override = max_page_size != NOT_CONFIGURED
|
75
|
+
@max_page_size = if max_page_size == NOT_CONFIGURED
|
76
|
+
nil
|
77
|
+
else
|
78
|
+
max_page_size
|
79
|
+
end
|
80
|
+
@has_default_page_size_override = default_page_size != NOT_CONFIGURED
|
81
|
+
@default_page_size = if default_page_size == NOT_CONFIGURED
|
82
|
+
nil
|
83
|
+
else
|
84
|
+
default_page_size
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def max_page_size=(new_value)
|
89
|
+
@has_max_page_size_override = true
|
90
|
+
@max_page_size = new_value
|
57
91
|
end
|
58
92
|
|
59
|
-
attr_writer :max_page_size
|
60
93
|
def max_page_size
|
61
|
-
@
|
94
|
+
if @has_max_page_size_override
|
95
|
+
@max_page_size
|
96
|
+
else
|
97
|
+
context.schema.default_max_page_size
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def has_max_page_size_override?
|
102
|
+
@has_max_page_size_override
|
103
|
+
end
|
104
|
+
|
105
|
+
def default_page_size=(new_value)
|
106
|
+
@has_default_page_size_override = true
|
107
|
+
@default_page_size = new_value
|
108
|
+
end
|
109
|
+
|
110
|
+
def default_page_size
|
111
|
+
if @has_default_page_size_override
|
112
|
+
@default_page_size
|
113
|
+
else
|
114
|
+
context.schema.default_page_size
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def has_default_page_size_override?
|
119
|
+
@has_default_page_size_override
|
62
120
|
end
|
63
121
|
|
64
122
|
attr_writer :first
|
65
123
|
# @return [Integer, nil]
|
66
124
|
# A clamped `first` value.
|
67
125
|
# (The underlying instance variable doesn't have limits on it.)
|
68
|
-
# If neither `first` nor `last` is given, but `
|
126
|
+
# If neither `first` nor `last` is given, but `default_page_size` is
|
127
|
+
# present, default_page_size is used for first. If `default_page_size`
|
128
|
+
# is greater than `max_page_size``, it'll be clamped down to
|
129
|
+
# `max_page_size`. If `default_page_size` is nil, use `max_page_size`.
|
69
130
|
def first
|
70
131
|
@first ||= begin
|
71
132
|
capped = limit_pagination_argument(@first_value, max_page_size)
|
72
133
|
if capped.nil? && last.nil?
|
73
|
-
capped = max_page_size
|
134
|
+
capped = limit_pagination_argument(default_page_size, max_page_size) || max_page_size
|
74
135
|
end
|
75
136
|
capped
|
76
137
|
end
|
77
138
|
end
|
78
139
|
|
140
|
+
# This is called by `Relay::RangeAdd` -- it can be overridden
|
141
|
+
# when `item` needs some modifications based on this connection's state.
|
142
|
+
#
|
143
|
+
# @param item [Object] An item newly added to `items`
|
144
|
+
# @return [Edge]
|
145
|
+
def range_add_edge(item)
|
146
|
+
edge_class.new(item, self)
|
147
|
+
end
|
148
|
+
|
79
149
|
attr_writer :last
|
80
150
|
# @return [Integer, nil] A clamped `last` value. (The underlying instance variable doesn't have limits on it)
|
81
151
|
def last
|
@@ -84,9 +154,15 @@ module GraphQL
|
|
84
154
|
|
85
155
|
# @return [Array<Edge>] {nodes}, but wrapped with Edge instances
|
86
156
|
def edges
|
87
|
-
@edges ||= nodes.map { |n|
|
157
|
+
@edges ||= nodes.map { |n| @edge_class.new(n, self) }
|
88
158
|
end
|
89
159
|
|
160
|
+
# @return [Class] A wrapper class for edges of this connection
|
161
|
+
attr_accessor :edge_class
|
162
|
+
|
163
|
+
# @return [GraphQL::Schema::Field] The field this connection was returned by
|
164
|
+
attr_accessor :field
|
165
|
+
|
90
166
|
# @return [Array<Object>] A slice of {items}, constrained by {@first_value}/{@after_value}/{@last_value}/{@before_value}
|
91
167
|
def nodes
|
92
168
|
raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`"
|
@@ -147,23 +223,29 @@ module GraphQL
|
|
147
223
|
end
|
148
224
|
|
149
225
|
def decode(cursor)
|
150
|
-
context.schema.cursor_encoder.decode(cursor)
|
226
|
+
context.schema.cursor_encoder.decode(cursor, nonce: true)
|
227
|
+
end
|
228
|
+
|
229
|
+
def encode(cursor)
|
230
|
+
context.schema.cursor_encoder.encode(cursor, nonce: true)
|
151
231
|
end
|
152
232
|
|
153
233
|
# A wrapper around paginated items. It includes a {cursor} for pagination
|
154
234
|
# and could be extended with custom relationship-level data.
|
155
235
|
class Edge
|
156
|
-
|
236
|
+
attr_reader :node
|
237
|
+
|
238
|
+
def initialize(node, connection)
|
157
239
|
@connection = connection
|
158
|
-
@
|
240
|
+
@node = node
|
159
241
|
end
|
160
242
|
|
161
|
-
def
|
162
|
-
@
|
243
|
+
def parent
|
244
|
+
@connection.parent
|
163
245
|
end
|
164
246
|
|
165
247
|
def cursor
|
166
|
-
@connection.cursor_for(@
|
248
|
+
@cursor ||= @connection.cursor_for(@node)
|
167
249
|
end
|
168
250
|
end
|
169
251
|
end
|
@@ -6,20 +6,13 @@ module GraphQL
|
|
6
6
|
#
|
7
7
|
# Attach as a plugin.
|
8
8
|
#
|
9
|
-
# @example Using new default connections
|
10
|
-
# class MySchema < GraphQL::Schema
|
11
|
-
# use GraphQL::Pagination::Connections
|
12
|
-
# end
|
13
|
-
#
|
14
9
|
# @example Adding a custom wrapper
|
15
10
|
# class MySchema < GraphQL::Schema
|
16
|
-
# use GraphQL::Pagination::Connections
|
17
11
|
# connections.add(MyApp::SearchResults, MyApp::SearchResultsConnection)
|
18
12
|
# end
|
19
13
|
#
|
20
14
|
# @example Removing default connection support for arrays (they can still be manually wrapped)
|
21
15
|
# class MySchema < GraphQL::Schema
|
22
|
-
# use GraphQL::Pagination::Connections
|
23
16
|
# connections.delete(Array)
|
24
17
|
# end
|
25
18
|
#
|
@@ -28,18 +21,8 @@ module GraphQL
|
|
28
21
|
class ImplementationMissingError < GraphQL::Error
|
29
22
|
end
|
30
23
|
|
31
|
-
def
|
32
|
-
|
33
|
-
schema_defn.connections = self.new
|
34
|
-
else
|
35
|
-
# Unwrap a `.define` object
|
36
|
-
schema_defn = schema_defn.target
|
37
|
-
schema_defn.connections = self.new
|
38
|
-
schema_defn.class.connections = schema_defn.connections
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialize
|
24
|
+
def initialize(schema:)
|
25
|
+
@schema = schema
|
43
26
|
@wrappers = {}
|
44
27
|
add_default
|
45
28
|
end
|
@@ -52,29 +35,68 @@ module GraphQL
|
|
52
35
|
@wrappers.delete(nodes_class)
|
53
36
|
end
|
54
37
|
|
55
|
-
|
56
|
-
|
57
|
-
|
38
|
+
def all_wrappers
|
39
|
+
all_wrappers = {}
|
40
|
+
@schema.ancestors.reverse_each do |schema_class|
|
41
|
+
if schema_class.respond_to?(:connections) && (c = schema_class.connections)
|
42
|
+
all_wrappers.merge!(c.wrappers)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
all_wrappers
|
46
|
+
end
|
47
|
+
|
48
|
+
def wrapper_for(items, wrappers: all_wrappers)
|
58
49
|
impl = nil
|
59
|
-
|
60
|
-
|
50
|
+
|
51
|
+
items.class.ancestors.each { |cls|
|
52
|
+
impl = wrappers[cls]
|
61
53
|
break if impl
|
62
54
|
}
|
63
55
|
|
64
|
-
|
65
|
-
|
56
|
+
impl
|
57
|
+
end
|
58
|
+
|
59
|
+
# Used by the runtime to wrap values in connection wrappers.
|
60
|
+
# @api Private
|
61
|
+
def wrap(field, parent, items, arguments, context)
|
62
|
+
return items if GraphQL::Execution::Interpreter::RawValue === items
|
63
|
+
wrappers = context ? context.namespace(:connections)[:all_wrappers] : all_wrappers
|
64
|
+
impl = wrapper_for(items, wrappers: wrappers)
|
65
|
+
|
66
|
+
if impl
|
67
|
+
impl.new(
|
68
|
+
items,
|
69
|
+
context: context,
|
70
|
+
parent: parent,
|
71
|
+
field: field,
|
72
|
+
max_page_size: field.has_max_page_size? ? field.max_page_size : context.schema.default_max_page_size,
|
73
|
+
default_page_size: field.has_default_page_size? ? field.default_page_size : context.schema.default_page_size,
|
74
|
+
first: arguments[:first],
|
75
|
+
after: arguments[:after],
|
76
|
+
last: arguments[:last],
|
77
|
+
before: arguments[:before],
|
78
|
+
arguments: arguments,
|
79
|
+
edge_class: edge_class_for_field(field),
|
80
|
+
)
|
81
|
+
else
|
82
|
+
raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
|
66
83
|
end
|
84
|
+
end
|
67
85
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
86
|
+
# use an override if there is one
|
87
|
+
# @api private
|
88
|
+
def edge_class_for_field(field)
|
89
|
+
conn_type = field.type.unwrap
|
90
|
+
conn_type_edge_type = conn_type.respond_to?(:edge_class) && conn_type.edge_class
|
91
|
+
if conn_type_edge_type && conn_type_edge_type != Pagination::Connection::Edge
|
92
|
+
conn_type_edge_type
|
93
|
+
else
|
94
|
+
nil
|
95
|
+
end
|
77
96
|
end
|
97
|
+
protected
|
98
|
+
|
99
|
+
attr_reader :wrappers
|
78
100
|
|
79
101
|
private
|
80
102
|
|
@@ -102,6 +124,11 @@ module GraphQL
|
|
102
124
|
if defined?(Mongoid::Association::Referenced::HasMany::Targets::Enumerable)
|
103
125
|
add(Mongoid::Association::Referenced::HasMany::Targets::Enumerable, Pagination::MongoidRelationConnection)
|
104
126
|
end
|
127
|
+
|
128
|
+
# Mongoid 7.3+
|
129
|
+
if defined?(Mongoid::Association::Referenced::HasMany::Enumerable)
|
130
|
+
add(Mongoid::Association::Referenced::HasMany::Enumerable, Pagination::MongoidRelationConnection)
|
131
|
+
end
|
105
132
|
end
|
106
133
|
end
|
107
134
|
end
|
@@ -12,7 +12,7 @@ module GraphQL
|
|
12
12
|
|
13
13
|
def has_previous_page
|
14
14
|
if @has_previous_page.nil?
|
15
|
-
@has_previous_page = if
|
15
|
+
@has_previous_page = if after_offset && after_offset > 0
|
16
16
|
true
|
17
17
|
elsif last
|
18
18
|
# See whether there are any nodes _before_ the current offset.
|
@@ -29,10 +29,14 @@ module GraphQL
|
|
29
29
|
|
30
30
|
def has_next_page
|
31
31
|
if @has_next_page.nil?
|
32
|
-
@has_next_page = if
|
32
|
+
@has_next_page = if before_offset && before_offset > 0
|
33
33
|
true
|
34
34
|
elsif first
|
35
|
-
|
35
|
+
if @nodes && @nodes.count < first
|
36
|
+
false
|
37
|
+
else
|
38
|
+
relation_larger_than(sliced_nodes, @sliced_nodes_offset, first)
|
39
|
+
end
|
36
40
|
else
|
37
41
|
false
|
38
42
|
end
|
@@ -43,12 +47,20 @@ module GraphQL
|
|
43
47
|
def cursor_for(item)
|
44
48
|
load_nodes
|
45
49
|
# index in nodes + existing offset + 1 (because it's offset, not index)
|
46
|
-
offset = nodes.index(item) + 1 + (@paged_nodes_offset || 0)
|
47
|
-
|
50
|
+
offset = nodes.index(item) + 1 + (@paged_nodes_offset || 0) - (relation_offset(items) || 0)
|
51
|
+
encode(offset.to_s)
|
48
52
|
end
|
49
53
|
|
50
54
|
private
|
51
55
|
|
56
|
+
# @param relation [Object] A database query object
|
57
|
+
# @param _initial_offset [Integer] The number of items already excluded from the relation
|
58
|
+
# @param size [Integer] The value against which we check the relation size
|
59
|
+
# @return [Boolean] True if the number of items in this relation is larger than `size`
|
60
|
+
def relation_larger_than(relation, _initial_offset, size)
|
61
|
+
relation_count(set_limit(relation, size + 1)) == size + 1
|
62
|
+
end
|
63
|
+
|
52
64
|
# @param relation [Object] A database query object
|
53
65
|
# @return [Integer, nil] The offset value, or nil if there isn't one
|
54
66
|
def relation_offset(relation)
|
@@ -100,67 +112,107 @@ module GraphQL
|
|
100
112
|
end
|
101
113
|
end
|
102
114
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
@before_offset = before && offset_from_cursor(before)
|
115
|
+
def calculate_sliced_nodes_parameters
|
116
|
+
if defined?(@sliced_nodes_limit)
|
117
|
+
return
|
118
|
+
else
|
119
|
+
next_offset = relation_offset(items) || 0
|
120
|
+
relation_limit = relation_limit(items)
|
110
121
|
|
111
|
-
if
|
112
|
-
|
113
|
-
paginated_nodes = set_offset(paginated_nodes, previous_offset + @after_offset)
|
122
|
+
if after_offset
|
123
|
+
next_offset += after_offset
|
114
124
|
end
|
115
125
|
|
116
|
-
if
|
117
|
-
if
|
126
|
+
if before_offset && after_offset
|
127
|
+
if after_offset < before_offset
|
118
128
|
# Get the number of items between the two cursors
|
119
|
-
space_between =
|
120
|
-
|
129
|
+
space_between = before_offset - after_offset - 1
|
130
|
+
relation_limit = space_between
|
121
131
|
else
|
122
|
-
# TODO I think this is untested
|
123
132
|
# The cursors overextend one another to an empty set
|
124
|
-
|
133
|
+
@sliced_nodes_null_relation = true
|
125
134
|
end
|
126
|
-
elsif
|
135
|
+
elsif before_offset
|
127
136
|
# Use limit to cut off the tail of the relation
|
128
|
-
|
137
|
+
relation_limit = before_offset - 1
|
138
|
+
end
|
139
|
+
|
140
|
+
@sliced_nodes_limit = relation_limit
|
141
|
+
@sliced_nodes_offset = next_offset
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Apply `before` and `after` to the underlying `items`,
|
146
|
+
# returning a new relation.
|
147
|
+
def sliced_nodes
|
148
|
+
@sliced_nodes ||= begin
|
149
|
+
calculate_sliced_nodes_parameters
|
150
|
+
paginated_nodes = items
|
151
|
+
|
152
|
+
if @sliced_nodes_null_relation
|
153
|
+
paginated_nodes = null_relation(paginated_nodes)
|
154
|
+
else
|
155
|
+
if @sliced_nodes_limit
|
156
|
+
paginated_nodes = set_limit(paginated_nodes, @sliced_nodes_limit)
|
157
|
+
end
|
158
|
+
|
159
|
+
if @sliced_nodes_offset
|
160
|
+
paginated_nodes = set_offset(paginated_nodes, @sliced_nodes_offset)
|
161
|
+
end
|
129
162
|
end
|
130
163
|
|
131
164
|
paginated_nodes
|
132
165
|
end
|
133
166
|
end
|
134
167
|
|
168
|
+
# @return [Integer, nil]
|
169
|
+
def before_offset
|
170
|
+
@before_offset ||= before && offset_from_cursor(before)
|
171
|
+
end
|
172
|
+
|
173
|
+
# @return [Integer, nil]
|
174
|
+
def after_offset
|
175
|
+
@after_offset ||= after && offset_from_cursor(after)
|
176
|
+
end
|
177
|
+
|
135
178
|
# Apply `first` and `last` to `sliced_nodes`,
|
136
179
|
# returning a new relation
|
137
180
|
def limited_nodes
|
138
181
|
@limited_nodes ||= begin
|
139
|
-
|
182
|
+
calculate_sliced_nodes_parameters
|
183
|
+
if @sliced_nodes_null_relation
|
184
|
+
# it's an empty set
|
185
|
+
return sliced_nodes
|
186
|
+
end
|
187
|
+
relation_limit = @sliced_nodes_limit
|
188
|
+
relation_offset = @sliced_nodes_offset
|
140
189
|
|
141
|
-
if first && (relation_limit
|
190
|
+
if first && (relation_limit.nil? || relation_limit > first)
|
142
191
|
# `first` would create a stricter limit that the one already applied, so add it
|
143
|
-
|
192
|
+
relation_limit = first
|
144
193
|
end
|
145
194
|
|
146
195
|
if last
|
147
|
-
if
|
148
|
-
if last <=
|
196
|
+
if relation_limit
|
197
|
+
if last <= relation_limit
|
149
198
|
# `last` is a smaller slice than the current limit, so apply it
|
150
|
-
|
151
|
-
|
152
|
-
paginated_nodes = set_limit(paginated_nodes, last)
|
199
|
+
relation_offset += (relation_limit - last)
|
200
|
+
relation_limit = last
|
153
201
|
end
|
154
202
|
else
|
155
203
|
# No limit, so get the last items
|
156
|
-
sliced_nodes_count = relation_count(
|
157
|
-
|
158
|
-
|
159
|
-
paginated_nodes = set_limit(paginated_nodes, last)
|
204
|
+
sliced_nodes_count = relation_count(sliced_nodes)
|
205
|
+
relation_offset += (sliced_nodes_count - [last, sliced_nodes_count].min)
|
206
|
+
relation_limit = last
|
160
207
|
end
|
161
208
|
end
|
162
209
|
|
163
|
-
@paged_nodes_offset = relation_offset
|
210
|
+
@paged_nodes_offset = relation_offset
|
211
|
+
paginated_nodes = items
|
212
|
+
paginated_nodes = set_offset(paginated_nodes, relation_offset)
|
213
|
+
if relation_limit
|
214
|
+
paginated_nodes = set_limit(paginated_nodes, relation_limit)
|
215
|
+
end
|
164
216
|
paginated_nodes
|
165
217
|
end
|
166
218
|
end
|