graphql 1.7.6 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/function_generator.rb +1 -1
- data/lib/generators/graphql/install_generator.rb +14 -8
- data/lib/generators/graphql/loader_generator.rb +1 -1
- data/lib/generators/graphql/mutation_generator.rb +6 -1
- data/lib/generators/graphql/templates/function.erb +2 -2
- data/lib/generators/graphql/templates/loader.erb +2 -2
- data/lib/generators/graphql/templates/schema.erb +1 -1
- data/lib/graphql/argument.rb +25 -19
- data/lib/graphql/backtrace/tracer.rb +16 -22
- data/lib/graphql/backtrace.rb +1 -1
- data/lib/graphql/backwards_compatibility.rb +2 -3
- data/lib/graphql/base_type.rb +31 -31
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +14 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
- data/lib/graphql/define/assign_object_field.rb +5 -12
- data/lib/graphql/deprecated_dsl.rb +42 -0
- data/lib/graphql/directive.rb +1 -0
- data/lib/graphql/enum_type.rb +3 -1
- data/lib/graphql/execution/execute.rb +21 -13
- data/lib/graphql/execution/instrumentation.rb +82 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +1 -1
- data/lib/graphql/execution/lazy/resolve.rb +1 -3
- data/lib/graphql/execution/multiplex.rb +12 -29
- data/lib/graphql/execution.rb +1 -0
- data/lib/graphql/field.rb +21 -4
- data/lib/graphql/function.rb +14 -0
- data/lib/graphql/input_object_type.rb +3 -1
- data/lib/graphql/interface_type.rb +5 -3
- data/lib/graphql/internal_representation/node.rb +26 -14
- data/lib/graphql/internal_representation/visit.rb +3 -6
- data/lib/graphql/introspection/base_object.rb +16 -0
- data/lib/graphql/introspection/directive_location_enum.rb +11 -7
- data/lib/graphql/introspection/directive_type.rb +23 -16
- data/lib/graphql/introspection/dynamic_fields.rb +11 -0
- data/lib/graphql/introspection/entry_points.rb +29 -0
- data/lib/graphql/introspection/enum_value_type.rb +16 -11
- data/lib/graphql/introspection/field_type.rb +21 -12
- data/lib/graphql/introspection/input_value_type.rb +26 -23
- data/lib/graphql/introspection/schema_field.rb +7 -2
- data/lib/graphql/introspection/schema_type.rb +36 -22
- data/lib/graphql/introspection/type_by_name_field.rb +10 -2
- data/lib/graphql/introspection/type_kind_enum.rb +10 -6
- data/lib/graphql/introspection/type_type.rb +85 -23
- data/lib/graphql/introspection/typename_field.rb +1 -0
- data/lib/graphql/introspection.rb +3 -10
- data/lib/graphql/language/block_string.rb +47 -0
- data/lib/graphql/language/document_from_schema_definition.rb +280 -0
- data/lib/graphql/language/generation.rb +3 -182
- data/lib/graphql/language/lexer.rb +144 -69
- data/lib/graphql/language/lexer.rl +15 -4
- data/lib/graphql/language/nodes.rb +141 -78
- data/lib/graphql/language/parser.rb +677 -630
- data/lib/graphql/language/parser.y +18 -12
- data/lib/graphql/language/printer.rb +361 -0
- data/lib/graphql/language/token.rb +10 -3
- data/lib/graphql/language.rb +3 -0
- data/lib/graphql/non_null_type.rb +1 -1
- data/lib/graphql/object_type.rb +1 -6
- data/lib/graphql/query/arguments.rb +63 -32
- data/lib/graphql/query/context.rb +32 -2
- data/lib/graphql/query/literal_input.rb +4 -1
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query/result.rb +1 -1
- data/lib/graphql/query/variables.rb +21 -3
- data/lib/graphql/query.rb +19 -6
- data/lib/graphql/railtie.rb +109 -0
- data/lib/graphql/relay/connection_resolve.rb +3 -0
- data/lib/graphql/relay/connection_type.rb +5 -3
- data/lib/graphql/relay/edge_type.rb +2 -1
- data/lib/graphql/relay/global_id_resolve.rb +5 -1
- data/lib/graphql/relay/mongo_relation_connection.rb +40 -0
- data/lib/graphql/relay/mutation/instrumentation.rb +1 -1
- data/lib/graphql/relay/mutation/resolve.rb +5 -1
- data/lib/graphql/relay/relation_connection.rb +14 -19
- data/lib/graphql/relay/type_extensions.rb +30 -0
- data/lib/graphql/relay.rb +2 -0
- data/lib/graphql/scalar_type.rb +14 -2
- data/lib/graphql/schema/argument.rb +92 -0
- data/lib/graphql/schema/build_from_definition.rb +64 -18
- data/lib/graphql/schema/enum.rb +85 -0
- data/lib/graphql/schema/enum_value.rb +74 -0
- data/lib/graphql/schema/field.rb +372 -0
- data/lib/graphql/schema/finder.rb +153 -0
- data/lib/graphql/schema/input_object.rb +87 -0
- data/lib/graphql/schema/interface.rb +105 -0
- data/lib/graphql/schema/introspection_system.rb +93 -0
- data/lib/graphql/schema/late_bound_type.rb +32 -0
- data/lib/graphql/schema/list.rb +32 -0
- data/lib/graphql/schema/loader.rb +2 -2
- data/lib/graphql/schema/member/accepts_definition.rb +152 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +100 -0
- data/lib/graphql/schema/member/build_type.rb +137 -0
- data/lib/graphql/schema/member/cached_graphql_definition.rb +26 -0
- data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
- data/lib/graphql/schema/member/has_arguments.rb +50 -0
- data/lib/graphql/schema/member/has_fields.rb +130 -0
- data/lib/graphql/schema/member/instrumentation.rb +115 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +34 -0
- data/lib/graphql/schema/member.rb +28 -0
- data/lib/graphql/schema/middleware_chain.rb +5 -1
- data/lib/graphql/schema/mutation.rb +138 -0
- data/lib/graphql/schema/non_null.rb +38 -0
- data/lib/graphql/schema/object.rb +81 -0
- data/lib/graphql/schema/printer.rb +33 -266
- data/lib/graphql/schema/relay_classic_mutation.rb +87 -0
- data/lib/graphql/schema/rescue_middleware.rb +8 -7
- data/lib/graphql/schema/resolver.rb +122 -0
- data/lib/graphql/schema/scalar.rb +35 -0
- data/lib/graphql/schema/traversal.rb +102 -22
- data/lib/graphql/schema/union.rb +36 -0
- data/lib/graphql/schema/validation.rb +3 -2
- data/lib/graphql/schema.rb +381 -12
- data/lib/graphql/static_validation/definition_dependencies.rb +1 -1
- data/lib/graphql/static_validation/literal_validator.rb +16 -4
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +6 -6
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +15 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +11 -1
- data/lib/graphql/static_validation/validation_context.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -5
- data/lib/graphql/subscriptions/instrumentation.rb +5 -1
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +90 -16
- data/lib/graphql/tracing/data_dog_tracing.rb +49 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +26 -0
- data/lib/graphql/tracing/platform_tracing.rb +20 -7
- data/lib/graphql/tracing/scout_tracing.rb +2 -2
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/unresolved_type_error.rb +3 -2
- data/lib/graphql/upgrader/member.rb +894 -0
- data/lib/graphql/upgrader/schema.rb +37 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +5 -25
- data/readme.md +2 -2
- data/spec/dummy/app/channels/graphql_channel.rb +23 -2
- data/spec/dummy/log/development.log +239 -0
- data/spec/dummy/log/test.log +410 -0
- data/spec/dummy/test/system/action_cable_subscription_test.rb +4 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-xYZjAnuuzgR79fcznLTQtSdh6AARxu8FcQ_J6p7L3U.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/13/13HiV12xyoQvT-1L39ZzLwMZxjyaGMiENmfw7f-QTIc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3W/3Wtf5pCWdqq0AB-iB0Y9uUNrTkruRxIEf1XFn_BETU0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5i/5iguGafb4hOn8262Kn8Q37ogNN9MxxQKGKNzHAzUcvI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8m/8mj2T6yy847Mc2Z7k3Xzh8O91hhVJt3NrPe8ASNDlIA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DT/DTQyMpr4ABZYQetsdRJ5A7S4jf1r3ie4FGOR7GZBNSs.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dq/DqJ5_yJPrP5iLlOQyTQsjAVI5FE5LCVDkED0f7GgsSo.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwDuCV-XpnCtjNkvhpJfBuxXMk0b5AD3L9eR6M-wcy0.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UL/ULdjhhb0bRuqmaG7XSZlFYzGYCXTDnqZuJBTWRlzqgw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Up/UpPNgh0yYoUsyMDh5zWqe_U6qJIyTC6-dxMMAs1vvlM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wg/Wguh-szFGTI1gaL6npYwPekMXflugRei7F_mOyRucXg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X-/X-khLYMA9mqFRPg3zAi86mREDxpKl4bdKYp3uF6WHos.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bi/BIkdhfxsezxM4q-HZ4oCNTq97WEJTigcq0tpX2cDvbY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ff/FfxmA4CMHQZT7exx0G7NS1Wpcnny0vzp-Jhc2H36bp8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gE/gEiiG4GZNy_djEjK2pHm_NgA-gyhLZhdQvo0Yt96GqE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gn/gnA9ZSqpjccNL2m8pe_jBvY6SinXlCzXDWyop83Od8s.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lO/lOAan3cMwCE_Hli6gsDML88xFNfn0nxPmvrSkW7eEOw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m1/M1pv8MJEPLXGLvS8QxVh3DSO9cI4mRt5FHFWdrvUj6o.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m7/m77qH7ZqH0_0SmwJbiKGDd-aLau1Dav847DC6ge46zY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sj/sjRjnjRB37lH2vrgtkdJ8Cz84__IJ978IuKTM7HcztI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/um/um1JrirR4hJhK-1rE-HywlyCi5ibgxHVrReiujZBWJM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v4/v4fwVytD7ITcE0_GDbslZEYud8a5Okm85fV1o7SDl6g.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v_/v_0PAQt0iipQjFP5zjgkkk9Stnpf4VzvnMv67d1Keuw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdT9U4MKxe1PyqNjVuCKMpCl3dxGCIRJIlwUTfh2DQU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xI/xIaxut_fEIhKBDqljTNwYaADK9kj3gG0ESrfHs-5_og.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y0/y0SJOqIx2fn1SKqOkAihsQow0trRJrSIyAswufVuoA8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zg/zgpzeaX-KZErHyGJ1aBH3ZusweNXMneVZule88XsIJI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zy/zYFltDy-8VC-uKq2BVEiJJyYXNFvVzAKuMlR3ZIYZsk.cache +0 -0
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/fixtures/upgrader/account.original.rb +19 -0
- data/spec/fixtures/upgrader/account.transformed.rb +20 -0
- data/spec/fixtures/upgrader/blame_range.original.rb +43 -0
- data/spec/fixtures/upgrader/blame_range.transformed.rb +30 -0
- data/spec/fixtures/upgrader/date_time.original.rb +24 -0
- data/spec/fixtures/upgrader/date_time.transformed.rb +23 -0
- data/spec/fixtures/upgrader/delete_project.original.rb +28 -0
- data/spec/fixtures/upgrader/delete_project.transformed.rb +27 -0
- data/spec/fixtures/upgrader/gist_order_field.original.rb +14 -0
- data/spec/fixtures/upgrader/gist_order_field.transformed.rb +13 -0
- data/spec/fixtures/upgrader/increment_count.original.rb +59 -0
- data/spec/fixtures/upgrader/increment_count.transformed.rb +50 -0
- data/spec/fixtures/upgrader/photo.original.rb +10 -0
- data/spec/fixtures/upgrader/photo.transformed.rb +12 -0
- data/spec/fixtures/upgrader/release_order.original.rb +15 -0
- data/spec/fixtures/upgrader/release_order.transformed.rb +14 -0
- data/spec/fixtures/upgrader/starrable.original.rb +49 -0
- data/spec/fixtures/upgrader/starrable.transformed.rb +46 -0
- data/spec/fixtures/upgrader/subscribable.original.rb +55 -0
- data/spec/fixtures/upgrader/subscribable.transformed.rb +51 -0
- data/spec/fixtures/upgrader/type_x.original.rb +65 -0
- data/spec/fixtures/upgrader/type_x.transformed.rb +56 -0
- data/spec/generators/graphql/function_generator_spec.rb +26 -0
- data/spec/generators/graphql/install_generator_spec.rb +1 -1
- data/spec/generators/graphql/loader_generator_spec.rb +24 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +3 -3
- data/spec/graphql/analysis/max_query_depth_spec.rb +3 -3
- data/spec/graphql/argument_spec.rb +21 -0
- data/spec/graphql/backtrace_spec.rb +10 -0
- data/spec/graphql/base_type_spec.rb +42 -0
- data/spec/graphql/boolean_type_spec.rb +3 -3
- data/spec/graphql/directive_spec.rb +3 -1
- data/spec/graphql/enum_type_spec.rb +18 -5
- data/spec/graphql/execution/execute_spec.rb +4 -4
- data/spec/graphql/execution/instrumentation_spec.rb +165 -0
- data/spec/graphql/execution/multiplex_spec.rb +2 -2
- data/spec/graphql/execution_error_spec.rb +18 -0
- data/spec/graphql/float_type_spec.rb +2 -2
- data/spec/graphql/id_type_spec.rb +1 -1
- data/spec/graphql/input_object_type_spec.rb +15 -2
- data/spec/graphql/int_type_spec.rb +2 -2
- data/spec/graphql/interface_type_spec.rb +12 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +2 -2
- data/spec/graphql/introspection/schema_type_spec.rb +2 -0
- data/spec/graphql/language/block_string_spec.rb +70 -0
- data/spec/graphql/language/document_from_schema_definition_spec.rb +770 -0
- data/spec/graphql/language/generation_spec.rb +21 -186
- data/spec/graphql/language/lexer_spec.rb +21 -1
- data/spec/graphql/language/nodes_spec.rb +21 -12
- data/spec/graphql/language/parser_spec.rb +1 -1
- data/spec/graphql/language/printer_spec.rb +203 -0
- data/spec/graphql/object_type_spec.rb +22 -0
- data/spec/graphql/query/arguments_spec.rb +25 -15
- data/spec/graphql/query/context_spec.rb +18 -0
- data/spec/graphql/query/executor_spec.rb +2 -1
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -8
- data/spec/graphql/query/variables_spec.rb +42 -1
- data/spec/graphql/query_spec.rb +31 -5
- data/spec/graphql/rake_task_spec.rb +3 -1
- data/spec/graphql/relay/base_connection_spec.rb +1 -1
- data/spec/graphql/relay/connection_instrumentation_spec.rb +2 -2
- data/spec/graphql/relay/connection_resolve_spec.rb +1 -1
- data/spec/graphql/relay/connection_type_spec.rb +1 -1
- data/spec/graphql/relay/mongo_relation_connection_spec.rb +474 -0
- data/spec/graphql/relay/mutation_spec.rb +9 -7
- data/spec/graphql/relay/range_add_spec.rb +5 -1
- data/spec/graphql/relay/relation_connection_spec.rb +65 -1
- data/spec/graphql/schema/argument_spec.rb +87 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +89 -5
- data/spec/graphql/schema/enum_spec.rb +74 -0
- data/spec/graphql/schema/field_spec.rb +225 -0
- data/spec/graphql/schema/finder_spec.rb +135 -0
- data/spec/graphql/schema/input_object_spec.rb +111 -0
- data/spec/graphql/schema/instrumentation_spec.rb +40 -0
- data/spec/graphql/schema/interface_spec.rb +185 -0
- data/spec/graphql/schema/introspection_system_spec.rb +39 -0
- data/spec/graphql/schema/member/accepts_definition_spec.rb +111 -0
- data/spec/graphql/schema/member/build_type_spec.rb +17 -0
- data/spec/graphql/schema/member/has_fields_spec.rb +129 -0
- data/spec/graphql/schema/member/type_system_helpers_spec.rb +63 -0
- data/spec/graphql/schema/mutation_spec.rb +148 -0
- data/spec/graphql/schema/object_spec.rb +175 -0
- data/spec/graphql/schema/printer_spec.rb +111 -15
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +38 -0
- data/spec/graphql/schema/rescue_middleware_spec.rb +11 -0
- data/spec/graphql/schema/resolver_spec.rb +131 -0
- data/spec/graphql/schema/scalar_spec.rb +95 -0
- data/spec/graphql/schema/traversal_spec.rb +31 -0
- data/spec/graphql/schema/union_spec.rb +65 -0
- data/spec/graphql/schema/validation_spec.rb +1 -1
- data/spec/graphql/schema/warden_spec.rb +11 -11
- data/spec/graphql/schema_spec.rb +55 -12
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -2
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
- data/spec/graphql/string_type_spec.rb +3 -3
- data/spec/graphql/subscriptions_spec.rb +273 -184
- data/spec/graphql/tracing/active_support_notifications_tracing_spec.rb +1 -1
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +47 -0
- data/spec/graphql/tracing/platform_tracing_spec.rb +60 -1
- data/spec/graphql/union_type_spec.rb +1 -1
- data/spec/graphql/upgrader/member_spec.rb +516 -0
- data/spec/graphql/upgrader/schema_spec.rb +82 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/dummy/schema.rb +53 -24
- data/spec/support/jazz.rb +544 -0
- data/spec/support/lazy_helpers.rb +21 -23
- data/spec/support/new_relic.rb +24 -0
- data/spec/support/star_trek/data.rb +109 -0
- data/spec/support/star_trek/schema.rb +388 -0
- data/spec/support/star_wars/data.rb +6 -7
- data/spec/support/star_wars/schema.rb +127 -171
- metadata +233 -11
- data/lib/graphql/introspection/arguments_field.rb +0 -7
- data/lib/graphql/introspection/enum_values_field.rb +0 -18
- data/lib/graphql/introspection/fields_field.rb +0 -13
- data/lib/graphql/introspection/input_fields_field.rb +0 -12
- data/lib/graphql/introspection/interfaces_field.rb +0 -11
- data/lib/graphql/introspection/of_type_field.rb +0 -6
- data/lib/graphql/introspection/possible_types_field.rb +0 -11
@@ -0,0 +1,372 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# test_via: ../object.rb
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Field
|
6
|
+
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
7
|
+
include GraphQL::Schema::Member::AcceptsDefinition
|
8
|
+
include GraphQL::Schema::Member::HasArguments
|
9
|
+
|
10
|
+
# @return [String] the GraphQL name for this field, camelized unless `camelize: false` is provided
|
11
|
+
attr_accessor :name
|
12
|
+
|
13
|
+
# @return [String]
|
14
|
+
attr_accessor :description
|
15
|
+
|
16
|
+
# @return [Symbol] Method or hash key to look up
|
17
|
+
attr_reader :method_sym
|
18
|
+
|
19
|
+
# @return [String] Method or hash key to look up
|
20
|
+
attr_reader :method_str
|
21
|
+
|
22
|
+
# @return [Class] The type that this field belongs to
|
23
|
+
attr_reader :owner
|
24
|
+
|
25
|
+
|
26
|
+
# @return [Class, nil] The {Schema::Resolver} this field was derived from, if there is one
|
27
|
+
def resolver
|
28
|
+
@resolver_class
|
29
|
+
end
|
30
|
+
|
31
|
+
alias :mutation :resolver
|
32
|
+
|
33
|
+
# Create a field instance from a list of arguments, keyword arguments, and a block.
|
34
|
+
#
|
35
|
+
# This method implements prioritization between the `resolver` or `mutation` defaults
|
36
|
+
# and the local overrides via other keywords.
|
37
|
+
#
|
38
|
+
# It also normalizes positional arguments into keywords for {Schema::Field#initialize}.
|
39
|
+
# @param resolver [Class] A {GraphQL::Schema::Resolver} class to use for field configuration
|
40
|
+
# @param mutation [Class] A {GraphQL::Schema::Mutation} class to use for field configuration
|
41
|
+
# @return [GraphQL::Schema:Field] an instance of `self
|
42
|
+
# @see {.initialize} for other options
|
43
|
+
def self.from_options(name = nil, type = nil, desc = nil, resolver: nil, mutation: nil, **kwargs, &block)
|
44
|
+
if (parent_config = resolver || mutation)
|
45
|
+
# Get the parent config, merge in local overrides
|
46
|
+
kwargs = parent_config.field_options.merge(kwargs)
|
47
|
+
# Add a reference to that parent class
|
48
|
+
kwargs[:resolver_class] = parent_config
|
49
|
+
end
|
50
|
+
|
51
|
+
if name
|
52
|
+
kwargs[:name] = name
|
53
|
+
end
|
54
|
+
|
55
|
+
if !type.nil?
|
56
|
+
if type.is_a?(GraphQL::Field)
|
57
|
+
raise ArgumentError, "A GraphQL::Field was passed as the second argument, use the `field:` keyword for this instead."
|
58
|
+
end
|
59
|
+
if desc
|
60
|
+
if kwargs[:description]
|
61
|
+
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{kwargs[:description].inspect})"
|
62
|
+
end
|
63
|
+
|
64
|
+
kwargs[:description] = desc
|
65
|
+
kwargs[:type] = type
|
66
|
+
elsif (kwargs[:field] || kwargs[:function] || resolver || mutation) && type.is_a?(String)
|
67
|
+
# The return type should be copied from `field` or `function`, and the second positional argument is the description
|
68
|
+
kwargs[:description] = type
|
69
|
+
else
|
70
|
+
kwargs[:type] = type
|
71
|
+
end
|
72
|
+
end
|
73
|
+
new(**kwargs, &block)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @param name [Symbol] The underscore-cased version of this field name (will be camelized for the GraphQL API)
|
77
|
+
# @param return_type_expr [Class, GraphQL::BaseType, Array] The return type of this field
|
78
|
+
# @param desc [String] Field description
|
79
|
+
# @param owner [Class] The type that this field belongs to
|
80
|
+
# @param null [Boolean] `true` if this field may return `null`, `false` if it is never `null`
|
81
|
+
# @param description [String] Field description
|
82
|
+
# @param deprecation_reason [String] If present, the field is marked "deprecated" with this message
|
83
|
+
# @param method [Symbol] The method to call to resolve this field (defaults to `name`)
|
84
|
+
# @param hash_key [Object] The hash key to lookup to resolve this field (defaults to `name` or `name.to_s`)
|
85
|
+
# @param connection [Boolean] `true` if this field should get automagic connection behavior; default is to infer by `*Connection` in the return type name
|
86
|
+
# @param max_page_size [Integer] For connections, the maximum number of items to return from this field
|
87
|
+
# @param introspection [Boolean] If true, this field will be marked as `#introspection?` and the name may begin with `__`
|
88
|
+
# @param resolve [<#call(obj, args, ctx)>] **deprecated** for compatibility with <1.8.0
|
89
|
+
# @param field [GraphQL::Field, GraphQL::Schema::Field] **deprecated** for compatibility with <1.8.0
|
90
|
+
# @param function [GraphQL::Function] **deprecated** for compatibility with <1.8.0
|
91
|
+
# @param resolver_class [Class] (Private) A {Schema::Resolver} which this field was derived from. Use `resolver:` to create a field with a resolver.
|
92
|
+
# @param arguments [{String=>GraphQL::Schema::Argument, Hash}] Arguments for this field (may be added in the block, also)
|
93
|
+
# @param camelize [Boolean] If true, the field name will be camelized when building the schema
|
94
|
+
# @param complexity [Numeric] When provided, set the complexity for this field
|
95
|
+
# @param subscription_scope [Symbol, String] A key in `context` which will be used to scope subscription payloads
|
96
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, connection: nil, max_page_size: nil, resolve: nil, introspection: false, hash_key: nil, camelize: true, complexity: 1, extras: [], resolver_class: nil, subscription_scope: nil, arguments: {}, &definition_block)
|
97
|
+
|
98
|
+
if name.nil?
|
99
|
+
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
100
|
+
end
|
101
|
+
if !(field || function || mutation || resolver)
|
102
|
+
if type.nil?
|
103
|
+
raise ArgumentError, "missing second `type` argument or keyword `type:`"
|
104
|
+
end
|
105
|
+
if null.nil?
|
106
|
+
raise ArgumentError, "missing keyword argument null:"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
if (field || function || resolve || mutation) && extras.any?
|
110
|
+
raise ArgumentError, "keyword `extras:` may only be used with method-based resolve, please remove `field:`, `function:`, `resolve:`, or `mutation:`"
|
111
|
+
end
|
112
|
+
@name = camelize ? Member::BuildType.camelize(name.to_s) : name.to_s
|
113
|
+
@description = description
|
114
|
+
if field.is_a?(GraphQL::Schema::Field)
|
115
|
+
@field_instance = field
|
116
|
+
else
|
117
|
+
@field = field
|
118
|
+
end
|
119
|
+
@function = function
|
120
|
+
@resolve = resolve
|
121
|
+
@deprecation_reason = deprecation_reason
|
122
|
+
if method && hash_key
|
123
|
+
raise ArgumentError, "Provide `method:` _or_ `hash_key:`, not both. (called with: `method: #{method.inspect}, hash_key: #{hash_key.inspect}`)"
|
124
|
+
end
|
125
|
+
|
126
|
+
# TODO: I think non-string/symbol hash keys are wrongly normalized (eg `1` will not work)
|
127
|
+
method_name = method || hash_key || Member::BuildType.underscore(name.to_s)
|
128
|
+
|
129
|
+
@method_str = method_name.to_s
|
130
|
+
@method_sym = method_name.to_sym
|
131
|
+
@complexity = complexity
|
132
|
+
@return_type_expr = type
|
133
|
+
@return_type_null = null
|
134
|
+
@connection = connection
|
135
|
+
@max_page_size = max_page_size
|
136
|
+
@introspection = introspection
|
137
|
+
@extras = extras
|
138
|
+
@resolver_class = resolver_class
|
139
|
+
|
140
|
+
# Override the default from HasArguments
|
141
|
+
@own_arguments = {}
|
142
|
+
arguments.each do |name, arg|
|
143
|
+
if arg.is_a?(Hash)
|
144
|
+
argument(name: name, **arg)
|
145
|
+
else
|
146
|
+
@own_arguments[name] = arg
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
@owner = owner
|
151
|
+
@subscription_scope = subscription_scope
|
152
|
+
|
153
|
+
if definition_block
|
154
|
+
instance_eval(&definition_block)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def description(text = nil)
|
159
|
+
if text
|
160
|
+
@description = text
|
161
|
+
else
|
162
|
+
@description
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def complexity(new_complexity)
|
167
|
+
case new_complexity
|
168
|
+
when Proc
|
169
|
+
if new_complexity.parameters.size != 3
|
170
|
+
fail(
|
171
|
+
"A complexity proc should always accept 3 parameters: ctx, args, child_complexity. "\
|
172
|
+
"E.g.: complexity ->(ctx, args, child_complexity) { child_complexity * args[:limit] }"
|
173
|
+
)
|
174
|
+
else
|
175
|
+
@complexity = new_complexity
|
176
|
+
end
|
177
|
+
when Numeric
|
178
|
+
@complexity = new_complexity
|
179
|
+
else
|
180
|
+
raise("Invalid complexity: #{new_complexity.inspect} on #{@name}")
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
# @return [GraphQL::Field]
|
186
|
+
def to_graphql
|
187
|
+
# this field was previously defined and passed here, so delegate to it
|
188
|
+
if @field_instance
|
189
|
+
return @field_instance.to_graphql
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
field_defn = if @field
|
194
|
+
@field.dup
|
195
|
+
elsif @function
|
196
|
+
GraphQL::Function.build_field(@function)
|
197
|
+
else
|
198
|
+
GraphQL::Field.new
|
199
|
+
end
|
200
|
+
|
201
|
+
field_defn.name = @name
|
202
|
+
if @return_type_expr
|
203
|
+
field_defn.type = -> { type }
|
204
|
+
end
|
205
|
+
|
206
|
+
if @connection.nil?
|
207
|
+
# Provide default based on type name
|
208
|
+
return_type_name = if @field || @function
|
209
|
+
Member::BuildType.to_type_name(field_defn.type)
|
210
|
+
elsif @return_type_expr
|
211
|
+
Member::BuildType.to_type_name(@return_type_expr)
|
212
|
+
else
|
213
|
+
raise "No connection info possible"
|
214
|
+
end
|
215
|
+
@connection = return_type_name.end_with?("Connection")
|
216
|
+
end
|
217
|
+
|
218
|
+
if @description
|
219
|
+
field_defn.description = @description
|
220
|
+
end
|
221
|
+
|
222
|
+
if @deprecation_reason
|
223
|
+
field_defn.deprecation_reason = @deprecation_reason
|
224
|
+
end
|
225
|
+
|
226
|
+
if @resolver_class
|
227
|
+
if @resolver_class < GraphQL::Schema::Mutation
|
228
|
+
field_defn.mutation = @resolver_class
|
229
|
+
end
|
230
|
+
field_defn.metadata[:resolver] = @resolver_class
|
231
|
+
end
|
232
|
+
|
233
|
+
field_defn.resolve = self.method(:resolve_field)
|
234
|
+
field_defn.connection = @connection
|
235
|
+
field_defn.connection_max_page_size = @max_page_size
|
236
|
+
field_defn.introspection = @introspection
|
237
|
+
field_defn.complexity = @complexity
|
238
|
+
field_defn.subscription_scope = @subscription_scope
|
239
|
+
|
240
|
+
# apply this first, so it can be overriden below
|
241
|
+
if @connection
|
242
|
+
# TODO: this could be a bit weird, because these fields won't be present
|
243
|
+
# after initialization, only in the `to_graphql` response.
|
244
|
+
# This calculation _could_ be moved up if need be.
|
245
|
+
argument :after, "String", "Returns the elements in the list that come after the specified global ID.", required: false
|
246
|
+
argument :before, "String", "Returns the elements in the list that come before the specified global ID.", required: false
|
247
|
+
argument :first, "Int", "Returns the first _n_ elements from the list.", required: false
|
248
|
+
argument :last, "Int", "Returns the last _n_ elements from the list.", required: false
|
249
|
+
end
|
250
|
+
|
251
|
+
arguments.each do |name, defn|
|
252
|
+
arg_graphql = defn.to_graphql
|
253
|
+
field_defn.arguments[arg_graphql.name] = arg_graphql
|
254
|
+
end
|
255
|
+
|
256
|
+
# Support a passed-in proc, one way or another
|
257
|
+
@resolve_proc = if @resolve
|
258
|
+
@resolve
|
259
|
+
elsif @function
|
260
|
+
@function
|
261
|
+
elsif @field
|
262
|
+
@field.resolve_proc
|
263
|
+
end
|
264
|
+
|
265
|
+
# Ok, `self` isn't a class, but this is for consistency with the classes
|
266
|
+
field_defn.metadata[:type_class] = self
|
267
|
+
|
268
|
+
field_defn
|
269
|
+
end
|
270
|
+
|
271
|
+
def type
|
272
|
+
@type ||= Member::BuildType.parse_type(@return_type_expr, null: @return_type_null)
|
273
|
+
rescue
|
274
|
+
raise ArgumentError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: #{$!.message}", $!.backtrace
|
275
|
+
end
|
276
|
+
|
277
|
+
# Implement {GraphQL::Field}'s resolve API.
|
278
|
+
#
|
279
|
+
# Eventually, we might hook up field instances to execution in another way. TBD.
|
280
|
+
def resolve_field(obj, args, ctx)
|
281
|
+
if @resolve_proc
|
282
|
+
# Might be nil, still want to call the func in that case
|
283
|
+
inner_obj = obj && obj.object
|
284
|
+
@resolve_proc.call(inner_obj, args, ctx)
|
285
|
+
elsif @resolver_class
|
286
|
+
inner_obj = obj && obj.object
|
287
|
+
singleton_inst = @resolver_class.new(object: inner_obj, context: ctx.query.context)
|
288
|
+
public_send_field(singleton_inst, args, ctx)
|
289
|
+
else
|
290
|
+
public_send_field(obj, args, ctx)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
# Find a way to resolve this field, checking:
|
295
|
+
#
|
296
|
+
# - Hash keys, if the wrapped object is a hash;
|
297
|
+
# - A method on the wrapped object;
|
298
|
+
# - Or, raise not implemented.
|
299
|
+
#
|
300
|
+
# This can be overridden by defining a method on the object type.
|
301
|
+
# @param obj [GraphQL::Schema::Object]
|
302
|
+
# @param ruby_kwargs [Hash<Symbol => Object>]
|
303
|
+
# @param ctx [GraphQL::Query::Context]
|
304
|
+
def resolve_field_method(obj, ruby_kwargs, ctx)
|
305
|
+
if obj.object.is_a?(Hash)
|
306
|
+
inner_object = obj.object
|
307
|
+
if inner_object.key?(@method_sym)
|
308
|
+
inner_object[@method_sym]
|
309
|
+
else
|
310
|
+
inner_object[@method_str]
|
311
|
+
end
|
312
|
+
elsif obj.object.respond_to?(@method_sym)
|
313
|
+
if ruby_kwargs.any?
|
314
|
+
obj.object.public_send(@method_sym, **ruby_kwargs)
|
315
|
+
else
|
316
|
+
obj.object.public_send(@method_sym)
|
317
|
+
end
|
318
|
+
else
|
319
|
+
raise <<-ERR
|
320
|
+
Failed to implement #{@owner.graphql_name}.#{@name}, tried:
|
321
|
+
|
322
|
+
- `#{obj.class}##{@method_sym}`, which did not exist
|
323
|
+
- `#{obj.object.class}##{@method_sym}`, which did not exist
|
324
|
+
- Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{obj.object}`, but it wasn't a Hash
|
325
|
+
|
326
|
+
To implement this field, define one of the methods above (and check for typos)
|
327
|
+
ERR
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
private
|
332
|
+
|
333
|
+
NO_ARGS = {}.freeze
|
334
|
+
|
335
|
+
def public_send_field(obj, graphql_args, field_ctx)
|
336
|
+
if graphql_args.any? || @extras.any?
|
337
|
+
# Splat the GraphQL::Arguments to Ruby keyword arguments
|
338
|
+
ruby_kwargs = graphql_args.to_kwargs
|
339
|
+
# Apply any `prepare` methods. Not great code organization, can this go somewhere better?
|
340
|
+
arguments.each do |name, arg_defn|
|
341
|
+
ruby_kwargs_key = arg_defn.keyword
|
342
|
+
if ruby_kwargs.key?(ruby_kwargs_key) && arg_defn.prepare
|
343
|
+
ruby_kwargs[ruby_kwargs_key] = arg_defn.prepare_value(obj, ruby_kwargs[ruby_kwargs_key])
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
if @connection
|
348
|
+
# Remove pagination args before passing it to a user method
|
349
|
+
ruby_kwargs.delete(:first)
|
350
|
+
ruby_kwargs.delete(:last)
|
351
|
+
ruby_kwargs.delete(:before)
|
352
|
+
ruby_kwargs.delete(:after)
|
353
|
+
end
|
354
|
+
|
355
|
+
@extras.each do |extra_arg|
|
356
|
+
# TODO: provide proper tests for `:ast_node`, `:irep_node`, `:parent`, others?
|
357
|
+
ruby_kwargs[extra_arg] = field_ctx.public_send(extra_arg)
|
358
|
+
end
|
359
|
+
else
|
360
|
+
ruby_kwargs = NO_ARGS
|
361
|
+
end
|
362
|
+
|
363
|
+
|
364
|
+
if ruby_kwargs.any?
|
365
|
+
obj.public_send(@method_sym, **ruby_kwargs)
|
366
|
+
else
|
367
|
+
obj.public_send(@method_sym)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# Find schema members using string paths
|
6
|
+
#
|
7
|
+
# @example Finding object types
|
8
|
+
# MySchema.find("SomeObjectType")
|
9
|
+
#
|
10
|
+
# @example Finding fields
|
11
|
+
# MySchema.find("SomeObjectType.myField")
|
12
|
+
#
|
13
|
+
# @example Finding arguments
|
14
|
+
# MySchema.find("SomeObjectType.myField.anArgument")
|
15
|
+
#
|
16
|
+
# @example Finding directives
|
17
|
+
# MySchema.find("@include")
|
18
|
+
#
|
19
|
+
class Finder
|
20
|
+
class MemberNotFoundError < ArgumentError; end
|
21
|
+
|
22
|
+
def initialize(schema)
|
23
|
+
@schema = schema
|
24
|
+
end
|
25
|
+
|
26
|
+
def find(path)
|
27
|
+
path = path.split(".")
|
28
|
+
type_or_directive = path.shift
|
29
|
+
|
30
|
+
if type_or_directive.start_with?("@")
|
31
|
+
directive = schema.directives[type_or_directive[1..-1]]
|
32
|
+
|
33
|
+
if directive.nil?
|
34
|
+
raise MemberNotFoundError, "Could not find directive `#{type_or_directive}` in schema."
|
35
|
+
end
|
36
|
+
|
37
|
+
return directive if path.empty?
|
38
|
+
|
39
|
+
find_in_directive(directive, path: path)
|
40
|
+
else
|
41
|
+
type = schema.types[type_or_directive]
|
42
|
+
|
43
|
+
if type.nil?
|
44
|
+
raise MemberNotFoundError, "Could not find type `#{type_or_directive}` in schema."
|
45
|
+
end
|
46
|
+
|
47
|
+
return type if path.empty?
|
48
|
+
|
49
|
+
find_in_type(type, path: path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :schema
|
56
|
+
|
57
|
+
def find_in_directive(directive, path:)
|
58
|
+
argument_name = path.shift
|
59
|
+
argument = directive.arguments[argument_name]
|
60
|
+
|
61
|
+
if argument.nil?
|
62
|
+
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on directive #{directive}."
|
63
|
+
end
|
64
|
+
|
65
|
+
argument
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_in_type(type, path:)
|
69
|
+
case type
|
70
|
+
when GraphQL::ObjectType
|
71
|
+
find_in_fields_type(type, kind: "object", path: path)
|
72
|
+
when GraphQL::InterfaceType
|
73
|
+
find_in_fields_type(type, kind: "interface", path: path)
|
74
|
+
when GraphQL::InputObjectType
|
75
|
+
find_in_input_object(type, path: path)
|
76
|
+
when GraphQL::UnionType
|
77
|
+
# Error out if path that was provided is too long
|
78
|
+
# i.e UnionType.PossibleType.aField
|
79
|
+
# Use PossibleType.aField instead.
|
80
|
+
if invalid = path.first
|
81
|
+
raise MemberNotFoundError, "Cannot select union possible type `#{invalid}`. Select the type directly instead."
|
82
|
+
end
|
83
|
+
when GraphQL::EnumType
|
84
|
+
find_in_enum_type(type, path: path)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def find_in_fields_type(type, kind:, path:)
|
89
|
+
field_name = path.shift
|
90
|
+
field = schema.get_field(type, field_name)
|
91
|
+
|
92
|
+
if field.nil?
|
93
|
+
raise MemberNotFoundError, "Could not find field `#{field_name}` on #{kind} type `#{type}`."
|
94
|
+
end
|
95
|
+
|
96
|
+
return field if path.empty?
|
97
|
+
|
98
|
+
find_in_field(field, path: path)
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_in_field(field, path:)
|
102
|
+
argument_name = path.shift
|
103
|
+
argument = field.arguments[argument_name]
|
104
|
+
|
105
|
+
if argument.nil?
|
106
|
+
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
|
107
|
+
end
|
108
|
+
|
109
|
+
# Error out if path that was provided is too long
|
110
|
+
# i.e Type.field.argument.somethingBad
|
111
|
+
if invalid = path.first
|
112
|
+
raise MemberNotFoundError, "Cannot select member `#{invalid}` on a field."
|
113
|
+
end
|
114
|
+
|
115
|
+
argument
|
116
|
+
end
|
117
|
+
|
118
|
+
def find_in_input_object(input_object, path:)
|
119
|
+
field_name = path.shift
|
120
|
+
input_field = input_object.input_fields[field_name]
|
121
|
+
|
122
|
+
if input_field.nil?
|
123
|
+
raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object}`."
|
124
|
+
end
|
125
|
+
|
126
|
+
# Error out if path that was provided is too long
|
127
|
+
# i.e InputType.inputField.bad
|
128
|
+
if invalid = path.first
|
129
|
+
raise MemberNotFoundError, "Cannot select member `#{invalid}` on an input field."
|
130
|
+
end
|
131
|
+
|
132
|
+
input_field
|
133
|
+
end
|
134
|
+
|
135
|
+
def find_in_enum_type(enum_type, path:)
|
136
|
+
value_name = path.shift
|
137
|
+
enum_value = enum_type.values[value_name]
|
138
|
+
|
139
|
+
if enum_value.nil?
|
140
|
+
raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type}`."
|
141
|
+
end
|
142
|
+
|
143
|
+
# Error out if path that was provided is too long
|
144
|
+
# i.e Enum.VALUE.wat
|
145
|
+
if invalid = path.first
|
146
|
+
raise MemberNotFoundError, "Cannot select member `#{invalid}` on an enum value."
|
147
|
+
end
|
148
|
+
|
149
|
+
enum_value
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class InputObject < GraphQL::Schema::Member
|
5
|
+
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
|
+
extend Forwardable
|
7
|
+
extend GraphQL::Schema::Member::HasArguments
|
8
|
+
|
9
|
+
def initialize(values, context:, defaults_used:)
|
10
|
+
@context = context
|
11
|
+
@arguments = self.class.arguments_class.new(values, context: context, defaults_used: defaults_used)
|
12
|
+
# Symbolized, underscored hash:
|
13
|
+
@ruby_style_hash = @arguments.to_kwargs
|
14
|
+
# Apply prepares, not great to have it duplicated here.
|
15
|
+
self.class.arguments.each do |name, arg_defn|
|
16
|
+
ruby_kwargs_key = arg_defn.keyword
|
17
|
+
if @ruby_style_hash.key?(ruby_kwargs_key) && arg_defn.prepare
|
18
|
+
@ruby_style_hash[ruby_kwargs_key] = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [GraphQL::Query::Context] The context for this query
|
24
|
+
attr_reader :context
|
25
|
+
|
26
|
+
# @return [GraphQL::Query::Arguments] The underlying arguments instance
|
27
|
+
attr_reader :arguments
|
28
|
+
|
29
|
+
# Ruby-like hash behaviors, read-only
|
30
|
+
def_delegators :@ruby_style_hash, :to_h, :keys, :values, :each, :any?
|
31
|
+
|
32
|
+
# Lookup a key on this object, it accepts new-style underscored symbols
|
33
|
+
# Or old-style camelized identifiers.
|
34
|
+
# @param key [Symbol, String]
|
35
|
+
def [](key)
|
36
|
+
if @ruby_style_hash.key?(key)
|
37
|
+
@ruby_style_hash[key]
|
38
|
+
else
|
39
|
+
@arguments[key]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def key?(key)
|
44
|
+
@ruby_style_hash.key?(key) || @arguments.key?(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
# A copy of the Ruby-style hash
|
48
|
+
def to_kwargs
|
49
|
+
@ruby_style_hash.dup
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
# @return [Class<GraphQL::Arguments>]
|
54
|
+
attr_accessor :arguments_class
|
55
|
+
|
56
|
+
def argument(*args)
|
57
|
+
argument_defn = super
|
58
|
+
# Add a method access
|
59
|
+
arg_name = argument_defn.graphql_definition.name
|
60
|
+
define_method(Member::BuildType.underscore(arg_name)) do
|
61
|
+
@arguments.public_send(arg_name)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_graphql
|
66
|
+
type_defn = GraphQL::InputObjectType.new
|
67
|
+
type_defn.name = graphql_name
|
68
|
+
type_defn.description = description
|
69
|
+
type_defn.metadata[:type_class] = self
|
70
|
+
type_defn.mutation = mutation
|
71
|
+
arguments.each do |name, arg|
|
72
|
+
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
|
73
|
+
end
|
74
|
+
# Make a reference to a classic-style Arguments class
|
75
|
+
self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
|
76
|
+
# But use this InputObject class at runtime
|
77
|
+
type_defn.arguments_class = self
|
78
|
+
type_defn
|
79
|
+
end
|
80
|
+
|
81
|
+
def kind
|
82
|
+
GraphQL::TypeKinds::INPUT_OBJECT
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|