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,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
module Interface
|
5
|
+
include GraphQL::Schema::Member::GraphQLTypeNames
|
6
|
+
module DefinitionMethods
|
7
|
+
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
8
|
+
include GraphQL::Relay::TypeExtensions
|
9
|
+
include GraphQL::Schema::Member::BaseDSLMethods
|
10
|
+
include GraphQL::Schema::Member::TypeSystemHelpers
|
11
|
+
include GraphQL::Schema::Member::HasFields
|
12
|
+
|
13
|
+
# Methods defined in this block will be:
|
14
|
+
# - Added as class methods to this interface
|
15
|
+
# - Added as class methods to all child interfaces
|
16
|
+
def definition_methods(&block)
|
17
|
+
self::DefinitionMethods.module_eval(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Here's the tricky part. Make sure behavior keeps making its way down the inheritance chain.
|
21
|
+
def included(child_class)
|
22
|
+
if !child_class.is_a?(Class)
|
23
|
+
# In this case, it's been included into another interface.
|
24
|
+
# This is how interface inheritance is implemented
|
25
|
+
|
26
|
+
# Use an instance variable to tell whether it's been included previously or not;
|
27
|
+
# You can't use constant detection because constants are brought into scope
|
28
|
+
# by `include`, which has already happened at this point.
|
29
|
+
if !child_class.instance_variable_defined?(:@_definition_methods)
|
30
|
+
defn_methods_module = Module.new
|
31
|
+
child_class.instance_variable_set(:@_definition_methods, defn_methods_module)
|
32
|
+
child_class.const_set(:DefinitionMethods, defn_methods_module)
|
33
|
+
child_class.extend(child_class::DefinitionMethods)
|
34
|
+
end
|
35
|
+
|
36
|
+
# We need this before we can call `own_interfaces`
|
37
|
+
child_class.extend(Schema::Interface::DefinitionMethods)
|
38
|
+
|
39
|
+
child_class.own_interfaces << self
|
40
|
+
child_class.interfaces.each do |interface_defn|
|
41
|
+
child_class.extend(interface_defn::DefinitionMethods)
|
42
|
+
end
|
43
|
+
elsif child_class < GraphQL::Schema::Object
|
44
|
+
# This is being included into an object type, make sure it's using `implements(...)`
|
45
|
+
backtrace_line = caller(0, 10).find { |line| line.include?("schema/object.rb") && line.include?("in `implements'")}
|
46
|
+
if !backtrace_line
|
47
|
+
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
def orphan_types(*types)
|
55
|
+
if types.any?
|
56
|
+
@orphan_types = types
|
57
|
+
else
|
58
|
+
all_orphan_types = @orphan_types || []
|
59
|
+
all_orphan_types += super if defined?(super)
|
60
|
+
all_orphan_types.uniq
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_graphql
|
65
|
+
type_defn = GraphQL::InterfaceType.new
|
66
|
+
type_defn.name = graphql_name
|
67
|
+
type_defn.description = description
|
68
|
+
type_defn.orphan_types = orphan_types
|
69
|
+
fields.each do |field_name, field_inst|
|
70
|
+
field_defn = field_inst.graphql_definition
|
71
|
+
type_defn.fields[field_defn.name] = field_defn
|
72
|
+
end
|
73
|
+
type_defn.metadata[:type_class] = self
|
74
|
+
if respond_to?(:resolve_type)
|
75
|
+
type_defn.resolve_type = method(:resolve_type)
|
76
|
+
end
|
77
|
+
type_defn
|
78
|
+
end
|
79
|
+
|
80
|
+
def kind
|
81
|
+
GraphQL::TypeKinds::INTERFACE
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
|
86
|
+
def own_interfaces
|
87
|
+
@own_interfaces ||= []
|
88
|
+
end
|
89
|
+
|
90
|
+
def interfaces
|
91
|
+
own_interfaces + (own_interfaces.map { |i| i.own_interfaces }).flatten
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Extend this _after_ `DefinitionMethods` is defined, so it will be used
|
96
|
+
extend GraphQL::Schema::Member::AcceptsDefinition
|
97
|
+
|
98
|
+
extend DefinitionMethods
|
99
|
+
|
100
|
+
def unwrap
|
101
|
+
self
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class IntrospectionSystem
|
5
|
+
attr_reader :schema_type, :type_type, :typename_field
|
6
|
+
|
7
|
+
def initialize(schema)
|
8
|
+
@schema = schema
|
9
|
+
@built_in_namespace = GraphQL::Introspection
|
10
|
+
@custom_namespace = schema.introspection_namespace || @built_in_namespace
|
11
|
+
|
12
|
+
# Use to-graphql to avoid sharing with any previous instantiations
|
13
|
+
@schema_type = load_constant(:SchemaType).to_graphql
|
14
|
+
@type_type = load_constant(:TypeType).to_graphql
|
15
|
+
@field_type = load_constant(:FieldType).to_graphql
|
16
|
+
@directive_type = load_constant(:DirectiveType).to_graphql
|
17
|
+
@enum_value_type = load_constant(:EnumValueType).to_graphql
|
18
|
+
@input_value_type = load_constant(:InputValueType).to_graphql
|
19
|
+
@type_kind_enum = load_constant(:TypeKindEnum).to_graphql
|
20
|
+
@directive_location_enum = load_constant(:DirectiveLocationEnum).to_graphql
|
21
|
+
@entry_point_fields = get_fields_from_class(class_sym: :EntryPoints)
|
22
|
+
@dynamic_fields = get_fields_from_class(class_sym: :DynamicFields)
|
23
|
+
end
|
24
|
+
|
25
|
+
def object_types
|
26
|
+
[
|
27
|
+
@schema_type,
|
28
|
+
@type_type,
|
29
|
+
@field_type,
|
30
|
+
@directive_type,
|
31
|
+
@enum_value_type,
|
32
|
+
@input_value_type,
|
33
|
+
@type_kind_enum,
|
34
|
+
@directive_location_enum,
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
def entry_points
|
39
|
+
@entry_point_fields.values
|
40
|
+
end
|
41
|
+
|
42
|
+
def entry_point(name:)
|
43
|
+
@entry_point_fields[name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def dynamic_fields
|
47
|
+
@dynamic_fields.values
|
48
|
+
end
|
49
|
+
|
50
|
+
def dynamic_field(name:)
|
51
|
+
@dynamic_fields[name]
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def load_constant(class_name)
|
57
|
+
@custom_namespace.const_get(class_name)
|
58
|
+
rescue NameError
|
59
|
+
# Dup the built-in so that the cached fields aren't shared
|
60
|
+
@built_in_namespace.const_get(class_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_fields_from_class(class_sym:)
|
64
|
+
object_class = load_constant(class_sym)
|
65
|
+
object_type_defn = object_class.to_graphql
|
66
|
+
extracted_field_defns = {}
|
67
|
+
object_type_defn.all_fields.each do |field_defn|
|
68
|
+
inner_resolve = field_defn.resolve_proc
|
69
|
+
resolve_with_instantiate = PerFieldProxyResolve.new(object_class: object_class, inner_resolve: inner_resolve)
|
70
|
+
extracted_field_defns[field_defn.name] = field_defn.redefine(resolve: resolve_with_instantiate)
|
71
|
+
end
|
72
|
+
extracted_field_defns
|
73
|
+
end
|
74
|
+
|
75
|
+
class PerFieldProxyResolve
|
76
|
+
def initialize(object_class:, inner_resolve:)
|
77
|
+
@object_class = object_class
|
78
|
+
@inner_resolve = inner_resolve
|
79
|
+
end
|
80
|
+
|
81
|
+
def call(obj, args, ctx)
|
82
|
+
query_ctx = ctx.query.context
|
83
|
+
# Remove the QueryType wrapper
|
84
|
+
if obj.is_a?(GraphQL::Schema::Object)
|
85
|
+
obj = obj.object
|
86
|
+
end
|
87
|
+
wrapped_object = @object_class.new(obj, query_ctx)
|
88
|
+
@inner_resolve.call(wrapped_object, args, ctx)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
# A stand-in for a type which will be resolved in a given schema, by name.
|
5
|
+
# TODO: support argument types too, make this a public API somehow
|
6
|
+
# @api Private
|
7
|
+
class LateBoundType
|
8
|
+
attr_reader :name
|
9
|
+
def initialize(local_name)
|
10
|
+
@name = local_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def unwrap
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_non_null_type
|
18
|
+
GraphQL::NonNullType.new(of_type: self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_list_type
|
22
|
+
GraphQL::ListType.new(of_type: self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def inspect
|
26
|
+
"#<LateBoundType @name=#{name}>"
|
27
|
+
end
|
28
|
+
|
29
|
+
alias :to_s :inspect
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# Represents a list type in the schema.
|
6
|
+
# Wraps a {Schema::Member} as a list type.
|
7
|
+
# @see {Schema::Member::TypeSystemHelpers#to_list_type}
|
8
|
+
class List
|
9
|
+
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
10
|
+
include GraphQL::Schema::Member::TypeSystemHelpers
|
11
|
+
|
12
|
+
# @return [Class, Module] The inner type of this list, the type of which one or more objects may be present.
|
13
|
+
attr_reader :of_type
|
14
|
+
|
15
|
+
def initialize(of_type)
|
16
|
+
@of_type = of_type
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_graphql
|
20
|
+
@of_type.graphql_definition.to_list_type
|
21
|
+
end
|
22
|
+
|
23
|
+
def kind
|
24
|
+
GraphQL::TypeKinds::LIST
|
25
|
+
end
|
26
|
+
|
27
|
+
def unwrap
|
28
|
+
@of_type.unwrap
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -97,7 +97,7 @@ module GraphQL
|
|
97
97
|
}]
|
98
98
|
)
|
99
99
|
when "FIELD"
|
100
|
-
Field.define(
|
100
|
+
GraphQL::Field.define(
|
101
101
|
name: type["name"],
|
102
102
|
type: type_resolver.call(type["type"]),
|
103
103
|
description: type["description"],
|
@@ -138,7 +138,7 @@ module GraphQL
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
Argument.define(
|
141
|
+
GraphQL::Argument.define(
|
142
142
|
name: type["name"],
|
143
143
|
type: type_resolver.call(type["type"]),
|
144
144
|
description: type["description"],
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
# Support for legacy `accepts_definitions` functions.
|
7
|
+
#
|
8
|
+
# Keep the legacy handler hooked up. Class-based types and fields
|
9
|
+
# will call those legacy handlers during their `.to_graphql`
|
10
|
+
# methods.
|
11
|
+
#
|
12
|
+
# This can help out while transitioning from one to the other.
|
13
|
+
# Eventually, `GraphQL::{X}Type` objects will be removed entirely,
|
14
|
+
# But this can help during the transition.
|
15
|
+
#
|
16
|
+
# @example Applying a function to base object class
|
17
|
+
# # Here's the legacy-style config, which we're calling back to:
|
18
|
+
# GraphQL::ObjectType.accepts_definition({
|
19
|
+
# permission_level: ->(defn, value) { defn.metadata[:permission_level] = value }
|
20
|
+
# })
|
21
|
+
#
|
22
|
+
# class BaseObject < GraphQL::Schema::Object
|
23
|
+
# # Setup a named pass-through to the legacy config functions
|
24
|
+
# accepts_definition :permission_level
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# class Account < BaseObject
|
28
|
+
# # This value will be passed to the legacy handler:
|
29
|
+
# permission_level 1
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # The class gets a reader method which returns the args,
|
33
|
+
# # only marginally useful.
|
34
|
+
# Account.permission_level # => [1]
|
35
|
+
#
|
36
|
+
# # The legacy handler is called, as before:
|
37
|
+
# Account.graphql_definition.metadata[:permission_level] # => 1
|
38
|
+
module AcceptsDefinition
|
39
|
+
def self.included(child)
|
40
|
+
child.extend(AcceptsDefinitionDefinitionMethods)
|
41
|
+
child.prepend(ToGraphQLExtension)
|
42
|
+
child.prepend(InitializeExtension)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.extended(child)
|
46
|
+
if defined?(child::DefinitionMethods)
|
47
|
+
child::DefinitionMethods.include(AcceptsDefinitionDefinitionMethods)
|
48
|
+
child::DefinitionMethods.prepend(ToGraphQLExtension)
|
49
|
+
else
|
50
|
+
child.extend(AcceptsDefinitionDefinitionMethods)
|
51
|
+
# I tried to use `super`, but super isn't quite right
|
52
|
+
# since the method is defined in the same class itself,
|
53
|
+
# not the superclass
|
54
|
+
child.class_eval do
|
55
|
+
class << self
|
56
|
+
prepend(ToGraphQLExtension)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module AcceptsDefinitionDefinitionMethods
|
63
|
+
def accepts_definition(name)
|
64
|
+
own_accepts_definition_methods << name
|
65
|
+
|
66
|
+
ivar_name = "@#{name}_args"
|
67
|
+
if self.is_a?(Class)
|
68
|
+
define_singleton_method(name) do |*args|
|
69
|
+
if args.any?
|
70
|
+
instance_variable_set(ivar_name, args)
|
71
|
+
end
|
72
|
+
instance_variable_get(ivar_name) || (superclass.respond_to?(name) ? superclass.public_send(name) : nil)
|
73
|
+
end
|
74
|
+
|
75
|
+
define_method(name) do |*args|
|
76
|
+
if args.any?
|
77
|
+
instance_variable_set(ivar_name, args)
|
78
|
+
end
|
79
|
+
instance_variable_get(ivar_name)
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# Special handling for interfaces, define it here
|
83
|
+
# so it's appropriately passed down
|
84
|
+
self::DefinitionMethods.module_eval do
|
85
|
+
define_method(name) do |*args|
|
86
|
+
if args.any?
|
87
|
+
instance_variable_set(ivar_name, args)
|
88
|
+
end
|
89
|
+
instance_variable_get(ivar_name) || ((int = interfaces.first { |i| i.respond_to?()}) && int.public_send(name))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def accepts_definition_methods
|
96
|
+
inherited_methods = if self.is_a?(Class)
|
97
|
+
superclass.respond_to?(:accepts_definition_methods) ? superclass.accepts_definition_methods : []
|
98
|
+
elsif self.is_a?(Module)
|
99
|
+
m = []
|
100
|
+
ancestors.each do |a|
|
101
|
+
if a.respond_to?(:own_accepts_definition_methods)
|
102
|
+
m.concat(a.own_accepts_definition_methods)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
m
|
106
|
+
else
|
107
|
+
self.class.accepts_definition_methods
|
108
|
+
end
|
109
|
+
|
110
|
+
own_accepts_definition_methods + inherited_methods
|
111
|
+
end
|
112
|
+
|
113
|
+
def own_accepts_definition_methods
|
114
|
+
@own_accepts_definition_methods ||= []
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module ToGraphQLExtension
|
119
|
+
def to_graphql
|
120
|
+
defn = super
|
121
|
+
accepts_definition_methods.each do |method_name|
|
122
|
+
value = public_send(method_name)
|
123
|
+
if !value.nil?
|
124
|
+
defn = defn.redefine { public_send(method_name, *value) }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
defn
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
module InitializeExtension
|
132
|
+
def initialize(*args, **kwargs, &block)
|
133
|
+
self.class.accepts_definition_methods.each do |method_name|
|
134
|
+
if kwargs.key?(method_name)
|
135
|
+
value = kwargs.delete(method_name)
|
136
|
+
if !value.is_a?(Array)
|
137
|
+
value = [value]
|
138
|
+
end
|
139
|
+
instance_variable_set("@#{method_name}_args", value)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
super(*args, **kwargs, &block)
|
143
|
+
end
|
144
|
+
|
145
|
+
def accepts_definition_methods
|
146
|
+
self.class.accepts_definition_methods
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
# DSL methods shared by lots of things in the GraphQL Schema.
|
7
|
+
# @api private
|
8
|
+
# @see Classes that extend this, eg {GraphQL::Schema::Object}
|
9
|
+
module BaseDSLMethods
|
10
|
+
# Call this with a new name to override the default name for this schema member; OR
|
11
|
+
# call it without an argument to get the name of this schema member
|
12
|
+
#
|
13
|
+
# The default name is the Ruby constant name,
|
14
|
+
# without any namespaces and with any `-Type` suffix removed
|
15
|
+
# @param new_name [String]
|
16
|
+
# @return [String]
|
17
|
+
def graphql_name(new_name = nil)
|
18
|
+
case
|
19
|
+
when new_name
|
20
|
+
@graphql_name = new_name
|
21
|
+
when overridden = overridden_graphql_name
|
22
|
+
overridden
|
23
|
+
else # Fallback to Ruby constant name
|
24
|
+
raise NotImplementedError, 'Anonymous class should declare an `graphql_name`' if name.nil?
|
25
|
+
|
26
|
+
name.split("::").last.sub(/Type\Z/, "")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Just a convenience method to point out that people should use graphql_name instead
|
31
|
+
def name(new_name = nil)
|
32
|
+
return super() if new_name.nil?
|
33
|
+
|
34
|
+
fail(
|
35
|
+
"The new name override method is `graphql_name`, not `name`. Usage: "\
|
36
|
+
"graphql_name \"#{new_name}\""
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Call this method to provide a new description; OR
|
41
|
+
# call it without an argument to get the description
|
42
|
+
# @param new_description [String]
|
43
|
+
# @return [String]
|
44
|
+
def description(new_description = nil)
|
45
|
+
if new_description
|
46
|
+
@description = new_description
|
47
|
+
else
|
48
|
+
@description || find_inherited_method(:description, nil)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Boolean] If true, this object is part of the introspection system
|
53
|
+
def introspection(new_introspection = nil)
|
54
|
+
if !new_introspection.nil?
|
55
|
+
@introspection = new_introspection
|
56
|
+
else
|
57
|
+
@introspection || find_inherited_method(:introspection, false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# The mutation this type was derived from, if it was derived from a mutation
|
62
|
+
# @return [Class]
|
63
|
+
def mutation(mutation_class = nil)
|
64
|
+
if mutation_class
|
65
|
+
@mutation = mutation_class
|
66
|
+
end
|
67
|
+
@mutation
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [GraphQL::BaseType] Convert this type to a legacy-style object.
|
71
|
+
def to_graphql
|
72
|
+
raise NotImplementedError
|
73
|
+
end
|
74
|
+
|
75
|
+
def overridden_graphql_name
|
76
|
+
@graphql_name || find_inherited_method(:overridden_graphql_name, nil)
|
77
|
+
end
|
78
|
+
|
79
|
+
def unwrap
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def find_inherited_method(method_name, default_value)
|
86
|
+
if self.is_a?(Class)
|
87
|
+
superclass.respond_to?(method_name) ? superclass.public_send(method_name) : default_value
|
88
|
+
else
|
89
|
+
ancestors[1..-1].each do |ancestor|
|
90
|
+
if ancestor.respond_to?(method_name)
|
91
|
+
return ancestor.public_send(method_name)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
default_value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Member
|
5
|
+
# @api private
|
6
|
+
module BuildType
|
7
|
+
LIST_TYPE_ERROR = "Use an array of [T] or [T, null: true] for list types; other arrays are not supported"
|
8
|
+
|
9
|
+
module_function
|
10
|
+
# @param type_expr [String, Class, GraphQL::BaseType]
|
11
|
+
# @return [GraphQL::BaseType]
|
12
|
+
def parse_type(type_expr, null:)
|
13
|
+
list_type = false
|
14
|
+
|
15
|
+
return_type = case type_expr
|
16
|
+
when String
|
17
|
+
case type_expr
|
18
|
+
when "String"
|
19
|
+
GraphQL::STRING_TYPE
|
20
|
+
when "Int", "Integer"
|
21
|
+
GraphQL::INT_TYPE
|
22
|
+
when "Float"
|
23
|
+
GraphQL::FLOAT_TYPE
|
24
|
+
when "Boolean"
|
25
|
+
GraphQL::BOOLEAN_TYPE
|
26
|
+
when "ID"
|
27
|
+
GraphQL::ID_TYPE
|
28
|
+
when /\A\[.*\]\Z/
|
29
|
+
list_type = true
|
30
|
+
# List members are required by default
|
31
|
+
parse_type(type_expr[1..-2], null: false)
|
32
|
+
when /.*!\Z/
|
33
|
+
null = false
|
34
|
+
parse_type(type_expr[0..-2], null: true)
|
35
|
+
else
|
36
|
+
maybe_type = Object.const_get(type_expr)
|
37
|
+
case maybe_type
|
38
|
+
when GraphQL::BaseType
|
39
|
+
maybe_type
|
40
|
+
when Module
|
41
|
+
# This is a way to check that it's the right kind of module:
|
42
|
+
if maybe_type.respond_to?(:graphql_definition)
|
43
|
+
maybe_type
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Unexpected class/module found for GraphQL type: #{type_expr} (must be type definition class/module)"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
when GraphQL::BaseType, GraphQL::Schema::LateBoundType
|
50
|
+
type_expr
|
51
|
+
when Array
|
52
|
+
case type_expr.length
|
53
|
+
when 1
|
54
|
+
list_type = true
|
55
|
+
# List members are required by default
|
56
|
+
parse_type(type_expr.first, null: false)
|
57
|
+
when 2
|
58
|
+
inner_type, nullable_option = type_expr
|
59
|
+
if nullable_option.keys != [:null] || nullable_option.values != [true]
|
60
|
+
raise ArgumentError, LIST_TYPE_ERROR
|
61
|
+
end
|
62
|
+
list_type = true
|
63
|
+
parse_type(inner_type, null: true)
|
64
|
+
else
|
65
|
+
raise ArgumentError, LIST_TYPE_ERROR
|
66
|
+
end
|
67
|
+
when Module
|
68
|
+
# This is a way to check that it's the right kind of module:
|
69
|
+
if type_expr.respond_to?(:graphql_definition)
|
70
|
+
type_expr
|
71
|
+
else
|
72
|
+
# Eg `String` => GraphQL::STRING_TYPE
|
73
|
+
parse_type(type_expr.name, null: true)
|
74
|
+
end
|
75
|
+
when false
|
76
|
+
raise ArgumentError, "Received `false` instead of a type, maybe a `!` should be replaced with `null: true` (for fields) or `required: true` (for arguments)"
|
77
|
+
end
|
78
|
+
|
79
|
+
if return_type.nil?
|
80
|
+
raise "Unexpected type input: #{type_expr} (#{type_expr.class})"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Apply list_type first, that way the
|
84
|
+
# .to_non_null_type applies to the list type, not the inner type
|
85
|
+
if list_type
|
86
|
+
return_type = return_type.to_list_type
|
87
|
+
end
|
88
|
+
|
89
|
+
if !null
|
90
|
+
return_type = return_type.to_non_null_type
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
return_type
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_type_name(something)
|
98
|
+
case something
|
99
|
+
when GraphQL::BaseType, GraphQL::Schema::LateBoundType
|
100
|
+
something.unwrap.name
|
101
|
+
when Array
|
102
|
+
to_type_name(something.first)
|
103
|
+
when Module
|
104
|
+
if something.respond_to?(:graphql_name)
|
105
|
+
something.graphql_name
|
106
|
+
else
|
107
|
+
to_type_name(something.name)
|
108
|
+
end
|
109
|
+
when String
|
110
|
+
something.gsub(/\]\[\!/, "").split("::").last
|
111
|
+
when GraphQL::Schema::NonNull, GraphQL::Schema::List
|
112
|
+
to_type_name(something.unwrap)
|
113
|
+
else
|
114
|
+
raise "Unhandled to_type_name input: #{something} (#{something.class})"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def camelize(string)
|
119
|
+
return string unless string.include?("_")
|
120
|
+
camelized = string.split('_').map(&:capitalize).join
|
121
|
+
camelized[0] = camelized[0].downcase
|
122
|
+
if (match_data = string.match(/\A(_+)/))
|
123
|
+
camelized = "#{match_data[0]}#{camelized}"
|
124
|
+
end
|
125
|
+
camelized
|
126
|
+
end
|
127
|
+
|
128
|
+
def underscore(string)
|
129
|
+
string
|
130
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2') # URLDecoder -> URL_Decoder
|
131
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2') # someThing -> some_Thing
|
132
|
+
.downcase
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
# Adds a layer of caching over user-supplied `.to_graphql` methods.
|
7
|
+
# Users override `.to_graphql`, but all runtime code should use `.graphql_definition`.
|
8
|
+
# @api private
|
9
|
+
# @see concrete classes that extend this, eg {Schema::Object}
|
10
|
+
module CachedGraphQLDefinition
|
11
|
+
# A cached result of {.to_graphql}.
|
12
|
+
# It's cached here so that user-overridden {.to_graphql} implementations
|
13
|
+
# are also cached
|
14
|
+
def graphql_definition
|
15
|
+
@graphql_definition ||= to_graphql
|
16
|
+
end
|
17
|
+
|
18
|
+
# Wipe out the cached graphql_definition so that `.to_graphql` will be called again.
|
19
|
+
def initialize_copy(original)
|
20
|
+
super
|
21
|
+
@graphql_definition = nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|