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,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
|