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,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
# These constants are interpreted as GraphQL types when defining fields or arguments
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# field :is_draft, Boolean, null: false
|
10
|
+
# field :id, ID, null: false
|
11
|
+
# field :score, Int, null: false
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
module GraphQLTypeNames
|
15
|
+
Boolean = "Boolean"
|
16
|
+
ID = "ID"
|
17
|
+
Int = "Int"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Member
|
5
|
+
module HasArguments
|
6
|
+
def self.included(cls)
|
7
|
+
cls.extend(ArgumentClassAccessor)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.extended(cls)
|
11
|
+
cls.extend(ArgumentClassAccessor)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @see {GraphQL::Schema::Argument#initialize} for parameters
|
15
|
+
# @return [GraphQL::Schema::Argument] An instance of {arguments_class}, created from `*args`
|
16
|
+
def argument(*args, **kwargs, &block)
|
17
|
+
kwargs[:owner] = self
|
18
|
+
arg_defn = self.argument_class.new(*args, **kwargs, &block)
|
19
|
+
own_arguments[arg_defn.name] = arg_defn
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Hash<String => GraphQL::Schema::Argument] Arguments defined on this thing, keyed by name. Includes inherited definitions
|
23
|
+
def arguments
|
24
|
+
inherited_arguments = ((self.is_a?(Class) && superclass.respond_to?(:arguments)) ? superclass.arguments : {})
|
25
|
+
# Local definitions override inherited ones
|
26
|
+
inherited_arguments.merge(own_arguments)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param new_arg_class [Class] A class to use for building argument definitions
|
30
|
+
def argument_class(new_arg_class = nil)
|
31
|
+
self.class.argument_class(new_arg_class)
|
32
|
+
end
|
33
|
+
|
34
|
+
module ArgumentClassAccessor
|
35
|
+
def argument_class(new_arg_class = nil)
|
36
|
+
if new_arg_class
|
37
|
+
@argument_class = new_arg_class
|
38
|
+
else
|
39
|
+
@argument_class || (superclass.respond_to?(:argument_class) ? superclass.argument_class : GraphQL::Schema::Argument)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def own_arguments
|
45
|
+
@own_arguments ||= {}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Member
|
5
|
+
# Shared code for Object and Interface
|
6
|
+
module HasFields
|
7
|
+
class << self
|
8
|
+
# When this module is added to a class,
|
9
|
+
# add a place for that class's default behaviors
|
10
|
+
def self.extended(child_class)
|
11
|
+
add_default_resolve_module(child_class)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a module which will have instance methods for implementing fields.
|
16
|
+
# These will be `super` methods for fields in interfaces, objects and mutations.
|
17
|
+
# Use an instance variable on the class instead of a constant
|
18
|
+
# so that module namespaces won't be an issue. (If we used constants,
|
19
|
+
# `child_class::DefaultResolve` might find a constant from an included module.)
|
20
|
+
def add_default_resolve_module(child_class)
|
21
|
+
if child_class.instance_variable_get(:@_default_resolve)
|
22
|
+
# This can happen when an object implements an interface,
|
23
|
+
# since that interface has the `included` hook above.
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
default_resolve_module = Module.new
|
28
|
+
child_class.instance_variable_set(:@_default_resolve, default_resolve_module)
|
29
|
+
child_class.include(default_resolve_module)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# When this is included into interfaces,
|
34
|
+
# add a place for default field behaviors
|
35
|
+
def included(child_class)
|
36
|
+
HasFields.add_default_resolve_module(child_class)
|
37
|
+
# Also, prepare a place for default field implementations
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
# When a subclass of objects are created,
|
42
|
+
# add a place for that subclass's default field behaviors
|
43
|
+
def inherited(child_class)
|
44
|
+
HasFields.add_default_resolve_module(child_class)
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
# Add a field to this object or interface with the given definition
|
49
|
+
# @see {GraphQL::Schema::Field#initialize} for method signature
|
50
|
+
# @return [void]
|
51
|
+
def field(*args, **kwargs, &block)
|
52
|
+
field_defn = field_class.from_options(*args, owner: self, **kwargs, &block)
|
53
|
+
add_field(field_defn)
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
|
58
|
+
def fields
|
59
|
+
# Local overrides take precedence over inherited fields
|
60
|
+
all_fields = {}
|
61
|
+
ancestors.reverse_each do |ancestor|
|
62
|
+
if ancestor.respond_to?(:own_fields)
|
63
|
+
all_fields.merge!(ancestor.own_fields)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
all_fields
|
67
|
+
end
|
68
|
+
|
69
|
+
# Register this field with the class, overriding a previous one if needed.
|
70
|
+
# Also, add a parent method for resolving this field.
|
71
|
+
# @param field_defn [GraphQL::Schema::Field]
|
72
|
+
# @return [void]
|
73
|
+
def add_field(field_defn)
|
74
|
+
own_fields[field_defn.name] = field_defn
|
75
|
+
if !method_defined?(field_defn.method_sym)
|
76
|
+
# Only add the super method if there isn't one already.
|
77
|
+
add_super_method(field_defn.name.inspect, field_defn.method_sym)
|
78
|
+
end
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Class] The class to initialize when adding fields to this kind of schema member
|
83
|
+
def field_class(new_field_class = nil)
|
84
|
+
if new_field_class
|
85
|
+
@field_class = new_field_class
|
86
|
+
elsif @field_class
|
87
|
+
@field_class
|
88
|
+
elsif self.is_a?(Class)
|
89
|
+
superclass.respond_to?(:field_class) ? superclass.field_class : GraphQL::Schema::Field
|
90
|
+
else
|
91
|
+
ancestor = ancestors[1..-1].find { |a| a.respond_to?(:field_class) && a.field_class }
|
92
|
+
ancestor ? ancestor.field_class : GraphQL::Schema::Field
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def global_id_field(field_name)
|
97
|
+
field field_name, "ID", null: false, resolve: GraphQL::Relay::GlobalIdResolve.new(type: self)
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Array<GraphQL::Schema::Field>] Fields defined on this class _specifically_, not parent classes
|
101
|
+
def own_fields
|
102
|
+
@own_fields ||= {}
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
# Find the magic module for holding super methods,
|
107
|
+
# and add a field named `method_name` for implementing the field
|
108
|
+
# called `field_name`.
|
109
|
+
# It will be the `super` method if the method is overwritten in the class definition.
|
110
|
+
def add_super_method(field_key, method_name)
|
111
|
+
default_resolve_module = @_default_resolve
|
112
|
+
if default_resolve_module.nil?
|
113
|
+
# This should have been set up in one of the inherited or included hooks above,
|
114
|
+
# if it wasn't, it's because those hooks weren't called because `super` wasn't present.
|
115
|
+
raise <<-ERR
|
116
|
+
Uh oh! #{self} doesn't have a default resolve module. This probably means that an `inherited` hook didn't call super.
|
117
|
+
Check `inherited` on #{self}'s superclasses.
|
118
|
+
ERR
|
119
|
+
end
|
120
|
+
default_resolve_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
121
|
+
def #{method_name}(**args)
|
122
|
+
field_inst = self.class.fields[#{field_key}] || raise(%|Failed to find field #{field_key} for \#{self.class} among \#{self.class.fields.keys}|)
|
123
|
+
field_inst.resolve_field_method(self, args, context)
|
124
|
+
end
|
125
|
+
RUBY
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# test_via: ../object.rb
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
class Schema
|
6
|
+
class Member
|
7
|
+
module Instrumentation
|
8
|
+
module_function
|
9
|
+
def instrument(type, field)
|
10
|
+
return_type = field.type.unwrap
|
11
|
+
if (return_type.is_a?(GraphQL::ObjectType) && return_type.metadata[:type_class]) ||
|
12
|
+
return_type.is_a?(GraphQL::InterfaceType) ||
|
13
|
+
(return_type.is_a?(GraphQL::UnionType) && return_type.possible_types.any? { |t| t.metadata[:type_class] })
|
14
|
+
field = apply_proxy(field)
|
15
|
+
end
|
16
|
+
|
17
|
+
field
|
18
|
+
end
|
19
|
+
|
20
|
+
def before_query(query)
|
21
|
+
# Get the root type for this query
|
22
|
+
root_node = query.irep_selection
|
23
|
+
if root_node.nil?
|
24
|
+
# It's an invalid query, nothing to do here
|
25
|
+
else
|
26
|
+
root_type = query.irep_selection.return_type
|
27
|
+
# If it has a wrapper, apply it
|
28
|
+
wrapper_class = root_type.metadata[:type_class]
|
29
|
+
if wrapper_class
|
30
|
+
new_root_value = wrapper_class.new(query.root_value, query.context)
|
31
|
+
query.root_value = new_root_value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def after_query(_query)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
module_function
|
42
|
+
|
43
|
+
def apply_proxy(field)
|
44
|
+
resolve_proc = field.resolve_proc
|
45
|
+
lazy_resolve_proc = field.lazy_resolve_proc
|
46
|
+
inner_return_type = field.type.unwrap
|
47
|
+
depth = list_depth(field.type)
|
48
|
+
|
49
|
+
field.redefine(
|
50
|
+
resolve: ProxiedResolve.new(inner_resolve: resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
|
51
|
+
lazy_resolve: ProxiedResolve.new(inner_resolve: lazy_resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def list_depth(type, starting_at = 0)
|
56
|
+
case type
|
57
|
+
when GraphQL::ListType
|
58
|
+
list_depth(type.of_type, starting_at + 1)
|
59
|
+
when GraphQL::NonNullType
|
60
|
+
list_depth(type.of_type, starting_at)
|
61
|
+
else
|
62
|
+
starting_at
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ProxiedResolve
|
67
|
+
def initialize(inner_resolve:, list_depth:, inner_return_type:)
|
68
|
+
@inner_resolve = inner_resolve
|
69
|
+
@inner_return_type = inner_return_type
|
70
|
+
@list_depth = list_depth
|
71
|
+
end
|
72
|
+
|
73
|
+
def call(obj, args, ctx)
|
74
|
+
result = @inner_resolve.call(obj, args, ctx)
|
75
|
+
if ctx.schema.lazy?(result)
|
76
|
+
# Wrap it later
|
77
|
+
result
|
78
|
+
elsif ctx.skip == result
|
79
|
+
result
|
80
|
+
else
|
81
|
+
proxy_to_depth(result, @list_depth, @inner_return_type, ctx)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def proxy_to_depth(obj, depth, type, ctx)
|
88
|
+
if obj.nil?
|
89
|
+
obj
|
90
|
+
elsif depth > 0
|
91
|
+
obj.map { |inner_obj| proxy_to_depth(inner_obj, depth - 1, type, ctx) }
|
92
|
+
else
|
93
|
+
concrete_type = case type
|
94
|
+
when GraphQL::UnionType, GraphQL::InterfaceType
|
95
|
+
ctx.query.resolve_type(type, obj)
|
96
|
+
when GraphQL::ObjectType
|
97
|
+
type
|
98
|
+
else
|
99
|
+
raise "unexpected proxying type #{type} for #{obj} at #{ctx.owner_type}.#{ctx.field.name}"
|
100
|
+
end
|
101
|
+
|
102
|
+
if concrete_type && (object_class = concrete_type.metadata[:type_class])
|
103
|
+
# use the query-level context here, since it won't be field-specific anyways
|
104
|
+
query_ctx = ctx.query.context
|
105
|
+
object_class.new(obj, query_ctx)
|
106
|
+
else
|
107
|
+
obj
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
module TypeSystemHelpers
|
7
|
+
# @return [Schema::NonNull] Make a non-null-type representation of this type
|
8
|
+
def to_non_null_type
|
9
|
+
GraphQL::Schema::NonNull.new(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Schema::List] Make a list-type representation of this type
|
13
|
+
def to_list_type
|
14
|
+
GraphQL::Schema::List.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean] true if this is a non-nullable type. A nullable list of non-nullables is considered nullable.
|
18
|
+
def non_null?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Boolean] true if this is a list type. A non-nullable list is considered a list.
|
23
|
+
def list?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [GraphQL::TypeKinds::TypeKind]
|
28
|
+
def kind
|
29
|
+
raise NotImplementedError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'graphql/schema/member/accepts_definition'
|
3
|
+
require 'graphql/schema/member/base_dsl_methods'
|
4
|
+
require 'graphql/schema/member/cached_graphql_definition'
|
5
|
+
require 'graphql/schema/member/graphql_type_names'
|
6
|
+
require 'graphql/schema/member/type_system_helpers'
|
7
|
+
require "graphql/relay/type_extensions"
|
8
|
+
|
9
|
+
module GraphQL
|
10
|
+
# The base class for things that make up the schema,
|
11
|
+
# eg objects, enums, scalars.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
class Schema
|
15
|
+
class Member
|
16
|
+
include GraphQLTypeNames
|
17
|
+
extend CachedGraphQLDefinition
|
18
|
+
extend GraphQL::Relay::TypeExtensions
|
19
|
+
extend BaseDSLMethods
|
20
|
+
extend TypeSystemHelpers
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'graphql/schema/member/has_arguments'
|
26
|
+
require 'graphql/schema/member/has_fields'
|
27
|
+
require 'graphql/schema/member/instrumentation'
|
28
|
+
require 'graphql/schema/member/build_type'
|
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
#
|
6
6
|
# Steps should call `next_step.call` to continue the chain, or _not_ call it to stop the chain.
|
7
7
|
class MiddlewareChain
|
8
|
-
extend
|
8
|
+
extend Forwardable
|
9
9
|
|
10
10
|
# @return [Array<#call(*args)>] Steps in this chain, will be called with arguments and `next_middleware`
|
11
11
|
attr_reader :steps, :final_step
|
@@ -38,6 +38,10 @@ module GraphQL
|
|
38
38
|
invoke_core(0, arguments)
|
39
39
|
end
|
40
40
|
|
41
|
+
def concat(callables)
|
42
|
+
callables.each { |c| add_middleware(c) }
|
43
|
+
end
|
44
|
+
|
41
45
|
private
|
42
46
|
|
43
47
|
def invoke_core(index, arguments)
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# This base class accepts configuration for a mutation root field,
|
6
|
+
# then it can be hooked up to your mutation root object type.
|
7
|
+
#
|
8
|
+
# If you want to customize how this class generates types, in your base class,
|
9
|
+
# override the various `generate_*` methods.
|
10
|
+
#
|
11
|
+
# @see {GraphQL::Schema::RelayClassicMutation} for an extension of this class with some conventions built-in.
|
12
|
+
#
|
13
|
+
# @example Creating a comment
|
14
|
+
# # Define the mutation:
|
15
|
+
# class Mutations::CreateComment < GraphQL::Schema::Mutation
|
16
|
+
# argument :body, String, required: true
|
17
|
+
# argument :post_id, ID, required: true
|
18
|
+
#
|
19
|
+
# field :comment, Types::Comment, null: true
|
20
|
+
# field :error_messages, [String], null: false
|
21
|
+
#
|
22
|
+
# def resolve(body:, post_id:)
|
23
|
+
# post = Post.find(post_id)
|
24
|
+
# comment = post.comments.build(body: body, author: context[:current_user])
|
25
|
+
# if comment.save
|
26
|
+
# # Successful creation, return the created object with no errors
|
27
|
+
# {
|
28
|
+
# comment: comment,
|
29
|
+
# errors: [],
|
30
|
+
# }
|
31
|
+
# else
|
32
|
+
# # Failed save, return the errors to the client
|
33
|
+
# {
|
34
|
+
# comment: nil,
|
35
|
+
# errors: comment.errors.full_messages
|
36
|
+
# }
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # Hook it up to your mutation:
|
42
|
+
# class Types::Mutation < GraphQL::Schema::Object
|
43
|
+
# field :create_comment, mutation: Mutations::CreateComment
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # Call it from GraphQL:
|
47
|
+
# result = MySchema.execute <<-GRAPHQL
|
48
|
+
# mutation {
|
49
|
+
# createComment(postId: "1", body: "Nice Post!") {
|
50
|
+
# errors
|
51
|
+
# comment {
|
52
|
+
# body
|
53
|
+
# author {
|
54
|
+
# login
|
55
|
+
# }
|
56
|
+
# }
|
57
|
+
# }
|
58
|
+
# }
|
59
|
+
# GRAPHQL
|
60
|
+
#
|
61
|
+
class Mutation < GraphQL::Schema::Resolver
|
62
|
+
extend GraphQL::Schema::Member::HasFields
|
63
|
+
|
64
|
+
class << self
|
65
|
+
# Override this method to handle legacy-style usages of `MyMutation.field`
|
66
|
+
def field(*args, &block)
|
67
|
+
if args.none?
|
68
|
+
raise ArgumentError, "#{name}.field is used for adding fields to this mutation. Use `mutation: #{name}` to attach this mutation instead."
|
69
|
+
else
|
70
|
+
super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Call this method to get the derived return type of the mutation,
|
75
|
+
# or use it as a configuration method to assign a return type
|
76
|
+
# instead of generating one.
|
77
|
+
# @param new_payload_type [Class, nil] If a type definition class is provided, it will be used as the return type of the mutation field
|
78
|
+
# @return [Class] The object type which this mutation returns.
|
79
|
+
def payload_type(new_payload_type = nil)
|
80
|
+
if new_payload_type
|
81
|
+
@payload_type = new_payload_type
|
82
|
+
end
|
83
|
+
@payload_type ||= generate_payload_type
|
84
|
+
end
|
85
|
+
|
86
|
+
alias :type :payload_type
|
87
|
+
alias :type_expr :payload_type
|
88
|
+
|
89
|
+
# An object class to use for deriving payload types
|
90
|
+
# @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
|
91
|
+
# @return [Class]
|
92
|
+
def object_class(new_class = nil)
|
93
|
+
if new_class
|
94
|
+
@object_class = new_class
|
95
|
+
end
|
96
|
+
@object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
|
97
|
+
end
|
98
|
+
|
99
|
+
def field_class(new_class = nil)
|
100
|
+
if new_class
|
101
|
+
@field_class = new_class
|
102
|
+
else
|
103
|
+
@field_class || find_inherited_method(:field_class, GraphQL::Schema::Field)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# An object class to use for deriving return types
|
108
|
+
# @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
|
109
|
+
# @return [Class]
|
110
|
+
def object_class(new_class = nil)
|
111
|
+
if new_class
|
112
|
+
@object_class = new_class
|
113
|
+
end
|
114
|
+
@object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# Build a subclass of {.object_class} based on `self`.
|
120
|
+
# This value will be cached as `{.payload_type}`.
|
121
|
+
# Override this hook to customize return type generation.
|
122
|
+
def generate_payload_type
|
123
|
+
mutation_name = graphql_name
|
124
|
+
mutation_fields = fields
|
125
|
+
mutation_class = self
|
126
|
+
Class.new(object_class) do
|
127
|
+
graphql_name("#{mutation_name}Payload")
|
128
|
+
description("Autogenerated return type of #{mutation_name}")
|
129
|
+
mutation(mutation_class)
|
130
|
+
mutation_fields.each do |name, f|
|
131
|
+
field(name, field: f)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# Wraps a {Schema::Member} when it is required.
|
6
|
+
# @see {Schema::Member::TypeSystemHelpers#to_non_null_type}
|
7
|
+
class NonNull
|
8
|
+
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
9
|
+
include GraphQL::Schema::Member::TypeSystemHelpers
|
10
|
+
attr_reader :of_type
|
11
|
+
def initialize(of_type)
|
12
|
+
@of_type = of_type
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_graphql
|
16
|
+
@of_type.graphql_definition.to_non_null_type
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [true]
|
20
|
+
def non_null?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Boolean] True if this type wraps a list type
|
25
|
+
def list?
|
26
|
+
@of_type.list?
|
27
|
+
end
|
28
|
+
|
29
|
+
def kind
|
30
|
+
GraphQL::TypeKinds::NON_NULL
|
31
|
+
end
|
32
|
+
|
33
|
+
def unwrap
|
34
|
+
@of_type.unwrap
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Object < GraphQL::Schema::Member
|
6
|
+
extend GraphQL::Schema::Member::AcceptsDefinition
|
7
|
+
extend GraphQL::Schema::Member::HasFields
|
8
|
+
|
9
|
+
# @return [Object] the application object this type is wrapping
|
10
|
+
attr_reader :object
|
11
|
+
|
12
|
+
# @return [GraphQL::Query::Context] the context instance for this query
|
13
|
+
attr_reader :context
|
14
|
+
|
15
|
+
def initialize(object, context)
|
16
|
+
@object = object
|
17
|
+
@context = context
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def implements(*new_interfaces)
|
22
|
+
new_interfaces.each do |int|
|
23
|
+
if int.is_a?(Module)
|
24
|
+
# Include the methods here,
|
25
|
+
# `.fields` will use the inheritance chain
|
26
|
+
# to find inherited fields
|
27
|
+
include(int)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
own_interfaces.concat(new_interfaces)
|
31
|
+
end
|
32
|
+
|
33
|
+
def interfaces
|
34
|
+
own_interfaces + (superclass <= GraphQL::Schema::Object ? superclass.interfaces : [])
|
35
|
+
end
|
36
|
+
|
37
|
+
def own_interfaces
|
38
|
+
@own_interfaces ||= []
|
39
|
+
end
|
40
|
+
|
41
|
+
# Include legacy-style interfaces, too
|
42
|
+
def fields
|
43
|
+
all_fields = super
|
44
|
+
interfaces.each do |int|
|
45
|
+
if int.is_a?(GraphQL::InterfaceType)
|
46
|
+
int_f = {}
|
47
|
+
int.fields.each do |name, legacy_field|
|
48
|
+
int_f[name] = field_class.from_options(name, field: legacy_field)
|
49
|
+
end
|
50
|
+
all_fields = int_f.merge(all_fields)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
all_fields
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [GraphQL::ObjectType]
|
57
|
+
def to_graphql
|
58
|
+
obj_type = GraphQL::ObjectType.new
|
59
|
+
obj_type.name = graphql_name
|
60
|
+
obj_type.description = description
|
61
|
+
obj_type.interfaces = interfaces
|
62
|
+
obj_type.introspection = introspection
|
63
|
+
obj_type.mutation = mutation
|
64
|
+
|
65
|
+
fields.each do |field_name, field_inst|
|
66
|
+
field_defn = field_inst.to_graphql
|
67
|
+
obj_type.fields[field_defn.name] = field_defn
|
68
|
+
end
|
69
|
+
|
70
|
+
obj_type.metadata[:type_class] = self
|
71
|
+
|
72
|
+
obj_type
|
73
|
+
end
|
74
|
+
|
75
|
+
def kind
|
76
|
+
GraphQL::TypeKinds::OBJECT
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|