graphql 1.7.6 → 1.8.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/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
|