graphql 1.2.6 → 1.3.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 +4 -4
- data/lib/graphql.rb +3 -1
- data/lib/graphql/analysis.rb +1 -0
- data/lib/graphql/analysis/analyze_query.rb +1 -0
- data/lib/graphql/analysis/field_usage.rb +1 -0
- data/lib/graphql/analysis/max_query_complexity.rb +1 -0
- data/lib/graphql/analysis/max_query_depth.rb +1 -0
- data/lib/graphql/analysis/query_complexity.rb +1 -0
- data/lib/graphql/analysis/query_depth.rb +1 -0
- data/lib/graphql/analysis/reducer_state.rb +1 -0
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/argument.rb +1 -0
- data/lib/graphql/base_type.rb +16 -7
- data/lib/graphql/boolean_type.rb +1 -0
- data/lib/graphql/compatibility.rb +2 -0
- data/lib/graphql/compatibility/execution_specification.rb +113 -192
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +53 -0
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +195 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +186 -0
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +97 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +1 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +1 -0
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +1 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +1 -0
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/assign_argument.rb +1 -0
- data/lib/graphql/define/assign_connection.rb +1 -0
- data/lib/graphql/define/assign_enum_value.rb +1 -0
- data/lib/graphql/define/assign_global_id_field.rb +1 -0
- data/lib/graphql/define/assign_object_field.rb +1 -0
- data/lib/graphql/define/defined_object_proxy.rb +1 -0
- data/lib/graphql/define/instance_definable.rb +11 -12
- data/lib/graphql/define/non_null_with_bang.rb +1 -0
- data/lib/graphql/define/type_definer.rb +1 -0
- data/lib/graphql/directive.rb +1 -0
- data/lib/graphql/directive/deprecated_directive.rb +1 -0
- data/lib/graphql/directive/include_directive.rb +1 -0
- data/lib/graphql/directive/skip_directive.rb +1 -0
- data/lib/graphql/enum_type.rb +8 -1
- data/lib/graphql/execution.rb +5 -0
- data/lib/graphql/execution/directive_checks.rb +1 -0
- data/lib/graphql/execution/execute.rb +222 -0
- data/lib/graphql/execution/field_result.rb +52 -0
- data/lib/graphql/execution/lazy.rb +59 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +38 -0
- data/lib/graphql/execution/lazy/resolve.rb +68 -0
- data/lib/graphql/execution/selection_result.rb +84 -0
- data/lib/graphql/execution/typecast.rb +4 -4
- data/lib/graphql/execution_error.rb +1 -0
- data/lib/graphql/field.rb +68 -18
- data/lib/graphql/field/resolve.rb +1 -0
- data/lib/graphql/float_type.rb +1 -0
- data/lib/graphql/id_type.rb +1 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/int_type.rb +1 -0
- data/lib/graphql/interface_type.rb +6 -0
- data/lib/graphql/internal_representation.rb +2 -1
- data/lib/graphql/internal_representation/node.rb +2 -1
- data/lib/graphql/internal_representation/rewrite.rb +1 -0
- data/lib/graphql/internal_representation/selection.rb +85 -0
- data/lib/graphql/introspection.rb +1 -0
- data/lib/graphql/introspection/arguments_field.rb +1 -0
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/enum_values_field.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/fields_field.rb +1 -0
- data/lib/graphql/introspection/input_fields_field.rb +1 -0
- data/lib/graphql/introspection/input_value_type.rb +2 -1
- data/lib/graphql/introspection/interfaces_field.rb +1 -0
- data/lib/graphql/introspection/introspection_query.rb +1 -0
- data/lib/graphql/introspection/of_type_field.rb +1 -0
- data/lib/graphql/introspection/possible_types_field.rb +1 -0
- data/lib/graphql/introspection/schema_field.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +1 -0
- data/lib/graphql/introspection/type_by_name_field.rb +1 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/introspection/typename_field.rb +1 -0
- data/lib/graphql/invalid_null_error.rb +17 -7
- data/lib/graphql/language.rb +10 -0
- data/lib/graphql/language/comments.rb +2 -1
- data/lib/graphql/language/definition_slice.rb +1 -0
- data/lib/graphql/language/generation.rb +25 -24
- data/lib/graphql/language/nodes.rb +1 -0
- data/lib/graphql/language/token.rb +1 -0
- data/lib/graphql/language/visitor.rb +1 -0
- data/lib/graphql/list_type.rb +1 -0
- data/lib/graphql/non_null_type.rb +2 -1
- data/lib/graphql/object_type.rb +12 -0
- data/lib/graphql/query.rb +40 -43
- data/lib/graphql/query/arguments.rb +1 -0
- data/lib/graphql/query/context.rb +31 -7
- data/lib/graphql/query/executor.rb +8 -1
- data/lib/graphql/query/input_validation_result.rb +1 -0
- data/lib/graphql/query/literal_input.rb +1 -0
- data/lib/graphql/query/serial_execution.rb +3 -4
- data/lib/graphql/query/serial_execution/field_resolution.rb +15 -10
- data/lib/graphql/query/serial_execution/operation_resolution.rb +3 -5
- data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -5
- data/lib/graphql/query/serial_execution/value_resolution.rb +26 -11
- data/lib/graphql/query/variable_validation_error.rb +1 -0
- data/lib/graphql/query/variables.rb +1 -0
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/relay/array_connection.rb +3 -2
- data/lib/graphql/relay/base_connection.rb +20 -8
- data/lib/graphql/relay/connection_field.rb +1 -0
- data/lib/graphql/relay/connection_resolve.rb +14 -1
- data/lib/graphql/relay/connection_type.rb +1 -0
- data/lib/graphql/relay/edge.rb +1 -0
- data/lib/graphql/relay/edge_type.rb +1 -0
- data/lib/graphql/relay/global_id_resolve.rb +1 -0
- data/lib/graphql/relay/mutation.rb +13 -0
- data/lib/graphql/relay/node.rb +1 -0
- data/lib/graphql/relay/page_info.rb +1 -0
- data/lib/graphql/relay/relation_connection.rb +3 -2
- data/lib/graphql/runtime_type_error.rb +4 -0
- data/lib/graphql/scalar_type.rb +2 -1
- data/lib/graphql/schema.rb +116 -26
- data/lib/graphql/schema/base_64_encoder.rb +14 -0
- data/lib/graphql/schema/build_from_definition.rb +4 -0
- data/lib/graphql/schema/catchall_middleware.rb +1 -0
- data/lib/graphql/schema/default_type_error.rb +15 -0
- data/lib/graphql/schema/instrumented_field_map.rb +1 -0
- data/lib/graphql/schema/invalid_type_error.rb +1 -0
- data/lib/graphql/schema/loader.rb +5 -1
- data/lib/graphql/schema/middleware_chain.rb +1 -0
- data/lib/graphql/schema/possible_types.rb +1 -0
- data/lib/graphql/schema/printer.rb +3 -2
- data/lib/graphql/schema/reduce_types.rb +1 -0
- data/lib/graphql/schema/rescue_middleware.rb +3 -2
- data/lib/graphql/schema/timeout_middleware.rb +1 -0
- data/lib/graphql/schema/type_expression.rb +1 -0
- data/lib/graphql/schema/type_map.rb +1 -0
- data/lib/graphql/schema/unique_within_type.rb +1 -0
- data/lib/graphql/schema/validation.rb +57 -1
- data/lib/graphql/schema/warden.rb +1 -0
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/arguments_validator.rb +1 -0
- data/lib/graphql/static_validation/literal_validator.rb +1 -0
- data/lib/graphql/static_validation/message.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +6 -3
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +1 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -0
- data/lib/graphql/static_validation/type_stack.rb +1 -0
- data/lib/graphql/static_validation/validation_context.rb +2 -1
- data/lib/graphql/static_validation/validator.rb +2 -1
- data/lib/graphql/string_type.rb +1 -0
- data/lib/graphql/type_kinds.rb +1 -0
- data/lib/graphql/union_type.rb +13 -0
- data/lib/graphql/unresolved_type_error.rb +26 -5
- data/lib/graphql/version.rb +2 -1
- data/readme.md +1 -5
- data/spec/graphql/analysis/analyze_query_spec.rb +1 -0
- data/spec/graphql/analysis/field_usage_spec.rb +1 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +1 -0
- data/spec/graphql/analysis/max_query_depth_spec.rb +1 -0
- data/spec/graphql/analysis/query_complexity_spec.rb +1 -0
- data/spec/graphql/analysis/query_depth_spec.rb +1 -0
- data/spec/graphql/argument_spec.rb +1 -0
- data/spec/graphql/base_type_spec.rb +13 -0
- data/spec/graphql/boolean_type_spec.rb +1 -0
- data/spec/graphql/compatibility/execution_specification_spec.rb +1 -0
- data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +4 -0
- data/spec/graphql/compatibility/query_parser_specification_spec.rb +1 -0
- data/spec/graphql/compatibility/schema_parser_specification_spec.rb +1 -0
- data/spec/graphql/define/assign_argument_spec.rb +1 -0
- data/spec/graphql/define/instance_definable_spec.rb +1 -0
- data/spec/graphql/directive_spec.rb +1 -0
- data/spec/graphql/enum_type_spec.rb +10 -0
- data/spec/graphql/execution/execute_spec.rb +5 -0
- data/spec/graphql/execution/lazy_spec.rb +252 -0
- data/spec/graphql/execution/typecast_spec.rb +1 -0
- data/spec/graphql/execution_error_spec.rb +1 -0
- data/spec/graphql/field_spec.rb +17 -0
- data/spec/graphql/float_type_spec.rb +1 -0
- data/spec/graphql/id_type_spec.rb +1 -0
- data/spec/graphql/input_object_type_spec.rb +10 -0
- data/spec/graphql/int_type_spec.rb +1 -0
- data/spec/graphql/interface_type_spec.rb +10 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +1 -0
- data/spec/graphql/introspection/directive_type_spec.rb +1 -0
- data/spec/graphql/introspection/input_value_type_spec.rb +1 -0
- data/spec/graphql/introspection/introspection_query_spec.rb +1 -0
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/introspection/type_type_spec.rb +1 -0
- data/spec/graphql/language/definition_slice_spec.rb +1 -0
- data/spec/graphql/language/equality_spec.rb +1 -0
- data/spec/graphql/language/generation_spec.rb +1 -0
- data/spec/graphql/language/lexer_spec.rb +1 -0
- data/spec/graphql/language/nodes_spec.rb +1 -0
- data/spec/graphql/language/parser_spec.rb +1 -0
- data/spec/graphql/language/visitor_spec.rb +1 -0
- data/spec/graphql/list_type_spec.rb +1 -0
- data/spec/graphql/non_null_type_spec.rb +17 -0
- data/spec/graphql/object_type_spec.rb +19 -0
- data/spec/graphql/query/arguments_spec.rb +1 -0
- data/spec/graphql/query/context_spec.rb +1 -0
- data/spec/graphql/query/executor_spec.rb +1 -0
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -0
- data/spec/graphql/query/variables_spec.rb +1 -0
- data/spec/graphql/query_spec.rb +25 -0
- data/spec/graphql/relay/array_connection_spec.rb +1 -0
- data/spec/graphql/relay/base_connection_spec.rb +33 -4
- data/spec/graphql/relay/connection_field_spec.rb +1 -0
- data/spec/graphql/relay/connection_type_spec.rb +1 -0
- data/spec/graphql/relay/mutation_spec.rb +6 -0
- data/spec/graphql/relay/node_spec.rb +1 -0
- data/spec/graphql/relay/page_info_spec.rb +1 -0
- data/spec/graphql/relay/relation_connection_spec.rb +1 -0
- data/spec/graphql/scalar_type_spec.rb +1 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +9 -1
- data/spec/graphql/schema/catchall_middleware_spec.rb +1 -0
- data/spec/graphql/schema/loader_spec.rb +7 -0
- data/spec/graphql/schema/middleware_chain_spec.rb +1 -0
- data/spec/graphql/schema/printer_spec.rb +1 -0
- data/spec/graphql/schema/reduce_types_spec.rb +1 -0
- data/spec/graphql/schema/rescue_middleware_spec.rb +1 -0
- data/spec/graphql/schema/timeout_middleware_spec.rb +1 -0
- data/spec/graphql/schema/type_expression_spec.rb +1 -0
- data/spec/graphql/schema/unique_within_type_spec.rb +1 -0
- data/spec/graphql/schema/validation_spec.rb +55 -0
- data/spec/graphql/schema/warden_spec.rb +1 -0
- data/spec/graphql/schema_spec.rb +39 -0
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +515 -31
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +1 -0
- data/spec/graphql/static_validation/type_stack_spec.rb +1 -0
- data/spec/graphql/static_validation/validator_spec.rb +1 -0
- data/spec/graphql/string_type_spec.rb +1 -0
- data/spec/graphql/union_type_spec.rb +11 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/dairy_app.rb +1 -0
- data/spec/support/dairy_data.rb +1 -0
- data/spec/support/minimum_input_object.rb +1 -0
- data/spec/support/star_wars_data.rb +1 -0
- data/spec/support/star_wars_schema.rb +30 -7
- data/spec/support/static_validation_helpers.rb +1 -0
- metadata +24 -5
- data/lib/graphql/internal_representation/selections.rb +0 -41
@@ -1,11 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
class Query
|
3
4
|
class SerialExecution
|
4
5
|
module ValueResolution
|
5
|
-
def self.resolve(parent_type, field_defn, field_type, value,
|
6
|
+
def self.resolve(parent_type, field_defn, field_type, value, selection, query_ctx)
|
6
7
|
if value.nil? || value.is_a?(GraphQL::ExecutionError)
|
7
8
|
if field_type.kind.non_null?
|
8
|
-
|
9
|
+
if value.nil?
|
10
|
+
type_error = GraphQL::InvalidNullError.new(parent_type, field_defn, value)
|
11
|
+
query_ctx.schema.type_error(type_error, query_ctx)
|
12
|
+
end
|
13
|
+
raise GraphQL::Query::Executor::PropagateNull
|
9
14
|
else
|
10
15
|
nil
|
11
16
|
end
|
@@ -17,17 +22,25 @@ module GraphQL
|
|
17
22
|
field_type.coerce_result(value, query_ctx.query.warden)
|
18
23
|
when GraphQL::TypeKinds::LIST
|
19
24
|
wrapped_type = field_type.of_type
|
20
|
-
result =
|
21
|
-
|
22
|
-
|
25
|
+
result = []
|
26
|
+
i = 0
|
27
|
+
value.each do |inner_value|
|
28
|
+
inner_ctx = query_ctx.spawn(
|
29
|
+
key: i,
|
30
|
+
selection: selection,
|
31
|
+
parent_type: wrapped_type,
|
32
|
+
field: field_defn,
|
33
|
+
)
|
34
|
+
|
35
|
+
result << resolve(
|
23
36
|
parent_type,
|
24
37
|
field_defn,
|
25
38
|
wrapped_type,
|
26
39
|
inner_value,
|
27
|
-
|
40
|
+
selection,
|
28
41
|
inner_ctx,
|
29
42
|
)
|
30
|
-
|
43
|
+
i += 1
|
31
44
|
end
|
32
45
|
result
|
33
46
|
when GraphQL::TypeKinds::NON_NULL
|
@@ -37,14 +50,14 @@ module GraphQL
|
|
37
50
|
field_defn,
|
38
51
|
wrapped_type,
|
39
52
|
value,
|
40
|
-
|
53
|
+
selection,
|
41
54
|
query_ctx,
|
42
55
|
)
|
43
56
|
when GraphQL::TypeKinds::OBJECT
|
44
57
|
query_ctx.execution_strategy.selection_resolution.resolve(
|
45
58
|
value,
|
46
59
|
field_type,
|
47
|
-
|
60
|
+
selection,
|
48
61
|
query_ctx
|
49
62
|
)
|
50
63
|
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
@@ -53,14 +66,16 @@ module GraphQL
|
|
53
66
|
possible_types = query.possible_types(field_type)
|
54
67
|
|
55
68
|
if !possible_types.include?(resolved_type)
|
56
|
-
|
69
|
+
type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
|
70
|
+
query.schema.type_error(type_error, query_ctx)
|
71
|
+
raise GraphQL::Query::Executor::PropagateNull
|
57
72
|
else
|
58
73
|
resolve(
|
59
74
|
parent_type,
|
60
75
|
field_defn,
|
61
76
|
resolved_type,
|
62
77
|
value,
|
63
|
-
|
78
|
+
selection,
|
64
79
|
query_ctx,
|
65
80
|
)
|
66
81
|
end
|
data/lib/graphql/relay.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
module Relay
|
3
4
|
class ArrayConnection < BaseConnection
|
4
5
|
def cursor_from_node(item)
|
5
6
|
idx = starting_offset + sliced_nodes.find_index(item) + 1
|
6
|
-
|
7
|
+
encode(idx.to_s)
|
7
8
|
end
|
8
9
|
|
9
10
|
def has_next_page
|
@@ -35,7 +36,7 @@ module GraphQL
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def index_from_cursor(cursor)
|
38
|
-
|
39
|
+
decode(cursor).to_i
|
39
40
|
end
|
40
41
|
|
41
42
|
def starting_offset
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
module Relay
|
3
4
|
# Subclasses must implement:
|
@@ -15,13 +16,13 @@ module GraphQL
|
|
15
16
|
CURSOR_SEPARATOR = "---"
|
16
17
|
|
17
18
|
# Map of collection class names -> connection_classes
|
18
|
-
# eg {"Array" => ArrayConnection}
|
19
|
+
# eg `{"Array" => ArrayConnection}`
|
19
20
|
CONNECTION_IMPLEMENTATIONS = {}
|
20
21
|
|
21
22
|
class << self
|
22
23
|
# Find a connection implementation suitable for exposing `nodes`
|
23
24
|
#
|
24
|
-
# @param [Object] A collection of nodes (eg, Array, AR::Relation)
|
25
|
+
# @param nodes [Object] A collection of nodes (eg, Array, AR::Relation)
|
25
26
|
# @return [subclass of BaseConnection] a connection Class for wrapping `nodes`
|
26
27
|
def connection_for_nodes(nodes)
|
27
28
|
# Check for class _names_ because classes can be redefined in Rails development
|
@@ -39,8 +40,8 @@ module GraphQL
|
|
39
40
|
|
40
41
|
# Add `connection_class` as the connection wrapper for `nodes_class`
|
41
42
|
# eg, `RelationConnection` is the implementation for `AR::Relation`
|
42
|
-
# @param [Class] A class representing a collection (eg, Array, AR::Relation)
|
43
|
-
# @param [Class] A class implementing Connection methods
|
43
|
+
# @param nodes_class [Class] A class representing a collection (eg, Array, AR::Relation)
|
44
|
+
# @param connection_class [Class] A class implementing Connection methods
|
44
45
|
def register_connection_implementation(nodes_class, connection_class)
|
45
46
|
CONNECTION_IMPLEMENTATIONS[nodes_class.name] = connection_class
|
46
47
|
end
|
@@ -49,17 +50,28 @@ module GraphQL
|
|
49
50
|
attr_reader :nodes, :arguments, :max_page_size, :parent, :field
|
50
51
|
|
51
52
|
# Make a connection, wrapping `nodes`
|
52
|
-
# @param [Object] The collection of nodes
|
53
|
-
# @param Query arguments
|
54
|
-
# @param field [
|
53
|
+
# @param nodes [Object] The collection of nodes
|
54
|
+
# @param arguments [GraphQL::Query::Arguments] Query arguments
|
55
|
+
# @param field [GraphQL::Field] The underlying field
|
55
56
|
# @param max_page_size [Int] The maximum number of results to return
|
56
57
|
# @param parent [Object] The object which this collection belongs to
|
57
|
-
|
58
|
+
# @param context [GraphQL::Query::Context] The context from the field being resolved
|
59
|
+
def initialize(nodes, arguments, field: nil, max_page_size: nil, parent: nil, context: nil)
|
58
60
|
@nodes = nodes
|
59
61
|
@arguments = arguments
|
60
62
|
@max_page_size = max_page_size
|
61
63
|
@field = field
|
62
64
|
@parent = parent
|
65
|
+
@context = context
|
66
|
+
@encoder = context ? @context.schema.cursor_encoder : GraphQL::Schema::Base64Encoder
|
67
|
+
end
|
68
|
+
|
69
|
+
def encode(data)
|
70
|
+
@encoder.encode(data, nonce: true)
|
71
|
+
end
|
72
|
+
|
73
|
+
def decode(data)
|
74
|
+
@encoder.decode(data, nonce: true)
|
63
75
|
end
|
64
76
|
|
65
77
|
# Provide easy access to provided arguments:
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
module Relay
|
3
4
|
class ConnectionResolve
|
@@ -9,8 +10,20 @@ module GraphQL
|
|
9
10
|
|
10
11
|
def call(obj, args, ctx)
|
11
12
|
nodes = @underlying_resolve.call(obj, args, ctx)
|
13
|
+
if ctx.schema.lazy?(nodes)
|
14
|
+
@field.prepare_lazy(nodes, args, ctx).then { |resolved_nodes|
|
15
|
+
build_connection(resolved_nodes, args, obj, ctx)
|
16
|
+
}
|
17
|
+
else
|
18
|
+
build_connection(nodes, args, obj, ctx)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def build_connection(nodes, args, parent, ctx)
|
12
25
|
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(nodes)
|
13
|
-
connection_class.new(nodes, args, field: @field, max_page_size: @max_page_size, parent:
|
26
|
+
connection_class.new(nodes, args, field: @field, max_page_size: @max_page_size, parent: parent, context: ctx)
|
14
27
|
end
|
15
28
|
end
|
16
29
|
end
|
data/lib/graphql/relay/edge.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
module Relay
|
3
4
|
# Define a Relay mutation:
|
@@ -181,6 +182,18 @@ module GraphQL
|
|
181
182
|
mutation_result = nil
|
182
183
|
end
|
183
184
|
|
185
|
+
if ctx.schema.lazy?(mutation_result)
|
186
|
+
@mutation.field.prepare_lazy(mutation_result, args, ctx).then { |inner_obj|
|
187
|
+
build_result(inner_obj, args)
|
188
|
+
}
|
189
|
+
else
|
190
|
+
build_result(mutation_result, args)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def build_result(mutation_result, args)
|
184
197
|
if @wrap_result
|
185
198
|
@mutation.result_class.new(client_mutation_id: args[:input][:clientMutationId], result: mutation_result)
|
186
199
|
else
|
data/lib/graphql/relay/node.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
module Relay
|
3
4
|
# A connection implementation to expose SQL collection objects.
|
@@ -11,7 +12,7 @@ module GraphQL
|
|
11
12
|
raise("Can't generate cursor, item not found in connection: #{item}")
|
12
13
|
else
|
13
14
|
offset = starting_offset + item_index + 1
|
14
|
-
|
15
|
+
encode(offset.to_s)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
@@ -36,7 +37,7 @@ module GraphQL
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def offset_from_cursor(cursor)
|
39
|
-
|
40
|
+
decode(cursor).to_i
|
40
41
|
end
|
41
42
|
|
42
43
|
def starting_offset
|
data/lib/graphql/scalar_type.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
# # GraphQL::ScalarType
|
3
4
|
#
|
@@ -45,7 +46,7 @@ module GraphQL
|
|
45
46
|
def validate_non_null_input(value, warden)
|
46
47
|
result = Query::InputValidationResult.new
|
47
48
|
if coerce_non_null_input(value).nil?
|
48
|
-
result.add_problem("Could not coerce value #{
|
49
|
+
result.add_problem("Could not coerce value #{GraphQL::Language.serialize(value)} to #{name}")
|
49
50
|
end
|
50
51
|
result
|
51
52
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "graphql/schema/base_64_encoder"
|
1
3
|
require "graphql/schema/catchall_middleware"
|
4
|
+
require "graphql/schema/default_type_error"
|
2
5
|
require "graphql/schema/invalid_type_error"
|
3
6
|
require "graphql/schema/instrumented_field_map"
|
4
7
|
require "graphql/schema/middleware_chain"
|
@@ -51,12 +54,14 @@ module GraphQL
|
|
51
54
|
:query, :mutation, :subscription,
|
52
55
|
:query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
|
53
56
|
:max_depth, :max_complexity,
|
54
|
-
:orphan_types, :resolve_type,
|
57
|
+
:orphan_types, :resolve_type, :type_error,
|
55
58
|
:object_from_id, :id_from_object,
|
59
|
+
:cursor_encoder,
|
56
60
|
directives: ->(schema, directives) { schema.directives = directives.reduce({}) { |m, d| m[d.name] = d; m }},
|
57
61
|
instrument: -> (schema, type, instrumenter) { schema.instrumenters[type] << instrumenter },
|
58
62
|
query_analyzer: ->(schema, analyzer) { schema.query_analyzers << analyzer },
|
59
|
-
middleware: ->(schema, middleware) { schema.
|
63
|
+
middleware: ->(schema, middleware) { schema.user_middleware << middleware },
|
64
|
+
lazy_resolve: ->(schema, lazy_class, lazy_value_method) { schema.lazy_methods.set(lazy_class, lazy_value_method) },
|
60
65
|
rescue_from: ->(schema, err_class, &block) { schema.rescue_from(err_class, &block)}
|
61
66
|
|
62
67
|
attr_accessor \
|
@@ -64,7 +69,14 @@ module GraphQL
|
|
64
69
|
:query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
|
65
70
|
:max_depth, :max_complexity,
|
66
71
|
:orphan_types, :directives,
|
67
|
-
:query_analyzers, :
|
72
|
+
:query_analyzers, :user_middleware, :instrumenters, :lazy_methods,
|
73
|
+
:cursor_encoder
|
74
|
+
|
75
|
+
class << self
|
76
|
+
attr_accessor :default_execution_strategy
|
77
|
+
end
|
78
|
+
|
79
|
+
self.default_execution_strategy = GraphQL::Execution::Execute
|
68
80
|
|
69
81
|
BUILT_IN_TYPES = Hash[[INT_TYPE, STRING_TYPE, FLOAT_TYPE, BOOLEAN_TYPE, ID_TYPE].map{ |type| [type.name, type] }]
|
70
82
|
DIRECTIVES = [GraphQL::Directive::IncludeDirective, GraphQL::Directive::SkipDirective, GraphQL::Directive::DeprecatedDirective]
|
@@ -72,28 +84,51 @@ module GraphQL
|
|
72
84
|
|
73
85
|
attr_reader :static_validator, :object_from_id_proc, :id_from_object_proc, :resolve_type_proc
|
74
86
|
|
75
|
-
# @!attribute [r] middleware
|
76
|
-
# @return [Array<#call>] Middlewares suitable for MiddlewareChain, applied to fields during execution
|
77
|
-
|
78
|
-
# @param query [GraphQL::ObjectType] the query root for the schema
|
79
|
-
# @param mutation [GraphQL::ObjectType] the mutation root for the schema
|
80
|
-
# @param subscription [GraphQL::ObjectType] the subscription root for the schema
|
81
|
-
# @param max_depth [Integer] maximum query nesting (if it's greater, raise an error)
|
82
|
-
# @param types [Array<GraphQL::BaseType>] additional types to include in this schema
|
83
87
|
def initialize
|
84
88
|
@orphan_types = []
|
85
89
|
@directives = DIRECTIVES.reduce({}) { |m, d| m[d.name] = d; m }
|
86
90
|
@static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
|
87
|
-
@
|
91
|
+
@user_middleware = []
|
88
92
|
@query_analyzers = []
|
89
93
|
@resolve_type_proc = nil
|
90
94
|
@object_from_id_proc = nil
|
91
95
|
@id_from_object_proc = nil
|
96
|
+
@type_error_proc = DefaultTypeError
|
92
97
|
@instrumenters = Hash.new { |h, k| h[k] = [] }
|
98
|
+
@lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
|
99
|
+
@cursor_encoder = Base64Encoder
|
93
100
|
# Default to the built-in execution strategy:
|
94
|
-
@query_execution_strategy =
|
95
|
-
@mutation_execution_strategy =
|
96
|
-
@subscription_execution_strategy =
|
101
|
+
@query_execution_strategy = self.class.default_execution_strategy
|
102
|
+
@mutation_execution_strategy = self.class.default_execution_strategy
|
103
|
+
@subscription_execution_strategy = self.class.default_execution_strategy
|
104
|
+
end
|
105
|
+
|
106
|
+
def initialize_copy(other)
|
107
|
+
super
|
108
|
+
@orphan_types = other.orphan_types.dup
|
109
|
+
@directives = other.directives.dup
|
110
|
+
@static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
|
111
|
+
@user_middleware = other.user_middleware.dup
|
112
|
+
@middleware = nil
|
113
|
+
@query_analyzers = other.query_analyzers.dup
|
114
|
+
|
115
|
+
@possible_types = GraphQL::Schema::PossibleTypes.new(self)
|
116
|
+
|
117
|
+
@lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
|
118
|
+
other.lazy_methods.each { |lazy_class, lazy_method| @lazy_methods.set(lazy_class, lazy_method) }
|
119
|
+
|
120
|
+
@instrumenters = Hash.new { |h, k| h[k] = [] }
|
121
|
+
other.instrumenters.each do |key, insts|
|
122
|
+
@instrumenters[key].concat(insts)
|
123
|
+
end
|
124
|
+
|
125
|
+
if other.rescues?
|
126
|
+
@rescue_middleware = other.rescue_middleware
|
127
|
+
end
|
128
|
+
|
129
|
+
# This will be rebuilt when it's requested
|
130
|
+
# or during a later `define` call
|
131
|
+
@types = nil
|
97
132
|
end
|
98
133
|
|
99
134
|
def rescue_from(*args, &block)
|
@@ -107,12 +142,11 @@ module GraphQL
|
|
107
142
|
def define(**kwargs, &block)
|
108
143
|
super
|
109
144
|
ensure_defined
|
110
|
-
|
111
|
-
@types = GraphQL::Schema::ReduceTypes.reduce(all_types.compact)
|
112
|
-
build_instrumented_field_map
|
145
|
+
build_types_map
|
113
146
|
# Assert that all necessary configs are present:
|
114
147
|
validation_error = Validation.validate(self)
|
115
148
|
validation_error && raise(NotImplementedError, validation_error)
|
149
|
+
build_instrumented_field_map
|
116
150
|
nil
|
117
151
|
end
|
118
152
|
|
@@ -127,10 +161,11 @@ module GraphQL
|
|
127
161
|
end
|
128
162
|
end
|
129
163
|
|
130
|
-
|
131
164
|
# @see [GraphQL::Schema::Warden] Restricted access to members of a schema
|
132
165
|
# @return [GraphQL::Schema::TypeMap] `{ name => type }` pairs of types in this schema
|
133
|
-
|
166
|
+
def types
|
167
|
+
@types ||= build_types_map
|
168
|
+
end
|
134
169
|
|
135
170
|
# Execute a query on itself.
|
136
171
|
# See {Query#initialize} for arguments.
|
@@ -240,6 +275,35 @@ module GraphQL
|
|
240
275
|
@object_from_id_proc = new_proc
|
241
276
|
end
|
242
277
|
|
278
|
+
# When we encounter a type error during query execution, we call this hook.
|
279
|
+
#
|
280
|
+
# You can use this hook to write a log entry,
|
281
|
+
# add a {GraphQL::ExecutionError} to the response (with `ctx.add_error`)
|
282
|
+
# or raise an exception and halt query execution.
|
283
|
+
#
|
284
|
+
# @example A `nil` is encountered by a non-null field
|
285
|
+
# type_error ->(err, query_ctx) {
|
286
|
+
# err.is_a?(GraphQL::InvalidNullError) # => true
|
287
|
+
# }
|
288
|
+
#
|
289
|
+
# @example An object doesn't resolve to one of a {UnionType}'s members
|
290
|
+
# type_error ->(err, query_ctx) {
|
291
|
+
# err.is_a?(GraphQL::UnresolvedTypeError) # => true
|
292
|
+
# }
|
293
|
+
#
|
294
|
+
# @see {DefaultTypeError} is the default behavior.
|
295
|
+
# @param err [GraphQL::TypeError] The error encountered during execution
|
296
|
+
# @param ctx [GraphQL::Query::Context] The context for the field where the error occurred
|
297
|
+
# @return void
|
298
|
+
def type_error(err, ctx)
|
299
|
+
@type_error_proc.call(err, ctx)
|
300
|
+
end
|
301
|
+
|
302
|
+
# @param new_proc [#call] A new callable for handling type errors during execution
|
303
|
+
def type_error=(new_proc)
|
304
|
+
@type_error_proc = new_proc
|
305
|
+
end
|
306
|
+
|
243
307
|
# Get a unique identifier from this object
|
244
308
|
# @param object [Any] An application object
|
245
309
|
# @param type [GraphQL::BaseType] The current type definition
|
@@ -275,20 +339,46 @@ module GraphQL
|
|
275
339
|
# Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
|
276
340
|
class InvalidDocumentError < Error; end;
|
277
341
|
|
278
|
-
|
342
|
+
# @return [Symbol, nil] The method name to lazily resolve `obj`, or nil if `obj`'s class wasn't registered wtih {#lazy_resolve}.
|
343
|
+
def lazy_method_name(obj)
|
344
|
+
@lazy_methods.get(obj)
|
345
|
+
end
|
346
|
+
|
347
|
+
# @return [Boolean] True if this object should be lazily resolved
|
348
|
+
def lazy?(obj)
|
349
|
+
!!lazy_method_name(obj)
|
350
|
+
end
|
351
|
+
|
352
|
+
# @return [Array<#call>] Middlewares suitable for MiddlewareChain, applied to fields during execution
|
353
|
+
def middleware
|
354
|
+
@middleware ||= if @rescue_middleware
|
355
|
+
[@rescue_middleware].concat(@user_middleware)
|
356
|
+
else
|
357
|
+
@user_middleware
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
protected
|
362
|
+
|
363
|
+
def rescues?
|
364
|
+
!!@rescue_middleware
|
365
|
+
end
|
279
366
|
|
280
367
|
# Lazily create a middleware and add it to the schema
|
281
368
|
# (Don't add it if it's not used)
|
282
369
|
def rescue_middleware
|
283
|
-
@rescue_middleware ||=
|
284
|
-
middleware = GraphQL::Schema::RescueMiddleware.new
|
285
|
-
@middleware << middleware
|
286
|
-
middleware
|
287
|
-
end
|
370
|
+
@rescue_middleware ||= GraphQL::Schema::RescueMiddleware.new
|
288
371
|
end
|
289
372
|
|
373
|
+
private
|
374
|
+
|
290
375
|
def build_instrumented_field_map
|
291
376
|
@instrumented_field_map = InstrumentedFieldMap.new(self, @instrumenters[:field])
|
292
377
|
end
|
378
|
+
|
379
|
+
def build_types_map
|
380
|
+
all_types = orphan_types + [query, mutation, subscription, GraphQL::Introspection::SchemaType]
|
381
|
+
@types = GraphQL::Schema::ReduceTypes.reduce(all_types.compact)
|
382
|
+
end
|
293
383
|
end
|
294
384
|
end
|