graphql 1.10.1 → 1.13.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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +18 -2
- data/lib/generators/graphql/install_generator.rb +36 -6
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +2 -1
- data/lib/generators/graphql/object_generator.rb +54 -9
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/interface.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +3 -1
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +21 -33
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +24 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +126 -109
- data/lib/graphql/analysis/ast/visitor.rb +13 -5
- data/lib/graphql/analysis/ast.rb +11 -2
- data/lib/graphql/argument.rb +3 -3
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +34 -3
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +40 -9
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- data/lib/graphql/compatibility/execution_specification.rb +1 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/instance_definable.rb +34 -4
- data/lib/graphql/define/type_definer.rb +5 -5
- data/lib/graphql/deprecated_dsl.rb +18 -5
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/directive.rb +4 -4
- data/lib/graphql/enum_type.rb +7 -1
- data/lib/graphql/execution/errors.rb +110 -7
- data/lib/graphql/execution/execute.rb +8 -1
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +103 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +685 -421
- data/lib/graphql/execution/interpreter.rb +42 -13
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +25 -110
- data/lib/graphql/execution/multiplex.rb +37 -25
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/function.rb +4 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +7 -0
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +8 -4
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +4 -4
- data/lib/graphql/introspection/type_type.rb +16 -12
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +73 -25
- data/lib/graphql/language/lexer.rb +4 -3
- data/lib/graphql/language/lexer.rl +3 -3
- data/lib/graphql/language/nodes.rb +51 -89
- data/lib/graphql/language/parser.rb +552 -530
- data/lib/graphql/language/parser.y +114 -99
- data/lib/graphql/language/printer.rb +7 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/object_type.rb +44 -35
- data/lib/graphql/pagination/active_record_relation_connection.rb +14 -1
- data/lib/graphql/pagination/array_connection.rb +2 -2
- data/lib/graphql/pagination/connection.rb +75 -20
- data/lib/graphql/pagination/connections.rb +83 -31
- data/lib/graphql/pagination/relation_connection.rb +34 -14
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +4 -3
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +42 -7
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/serial_execution.rb +1 -0
- data/lib/graphql/query/validation_pipeline.rb +5 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +14 -4
- data/lib/graphql/query.rb +68 -13
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +26 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/mutation.rb +1 -0
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/range_add.rb +23 -9
- data/lib/graphql/relay/relation_connection.rb +8 -10
- data/lib/graphql/relay/type_extensions.rb +2 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/scalar_type.rb +16 -1
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +210 -12
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +213 -86
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +78 -2
- data/lib/graphql/schema/enum.rb +80 -9
- data/lib/graphql/schema/enum_value.rb +17 -6
- data/lib/graphql/schema/field/connection_extension.rb +46 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +285 -133
- data/lib/graphql/schema/find_inherited_value.rb +4 -1
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +97 -89
- data/lib/graphql/schema/interface.rb +24 -19
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +7 -1
- data/lib/graphql/schema/loader.rb +137 -103
- data/lib/graphql/schema/member/accepts_definition.rb +8 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -19
- data/lib/graphql/schema/member/build_type.rb +14 -7
- data/lib/graphql/schema/member/has_arguments.rb +205 -12
- data/lib/graphql/schema/member/has_ast_node.rb +4 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +95 -30
- data/lib/graphql/schema/member/has_interfaces.rb +90 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/instrumentation.rb +0 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/non_null.rb +5 -0
- data/lib/graphql/schema/object.rb +47 -46
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +32 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +123 -63
- data/lib/graphql/schema/scalar.rb +11 -1
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/timeout_middleware.rb +3 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +41 -1
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +12 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +68 -0
- data/lib/graphql/schema/validator.rb +174 -0
- data/lib/graphql/schema/warden.rb +153 -28
- data/lib/graphql/schema.rb +364 -330
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +8 -5
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +79 -43
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +8 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +9 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +42 -8
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +118 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +81 -30
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +33 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -4
- data/lib/graphql/subscriptions.rb +88 -45
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/platform_tracing.rb +43 -17
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +9 -33
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +3 -3
- data/lib/graphql/types/iso_8601_date_time.rb +25 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +53 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +15 -0
- data/lib/graphql/types/relay/node_field.rb +2 -20
- data/lib/graphql/types/relay/nodes_field.rb +2 -20
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -3
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/union_type.rb +2 -0
- data/lib/graphql/upgrader/member.rb +1 -0
- data/lib/graphql/upgrader/schema.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +65 -31
- data/readme.md +3 -6
- metadata +77 -112
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 853fa0482ef0c3bafe04dce77dff9bb685633a1e4c273fd234169f98d595352c
|
4
|
+
data.tar.gz: 6cf800af8dfc469f4d7a375ee22f6d98e03207799f813f10176916f09a0a4064
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bcd2b94fa64ab65fb47995a4896b08629bfc9b66f7797dfd4959ad8ccdb5332bf63ae49f5139c7d1766b3d72cb500da257c611e628dc5db36ae26b472c5d51c
|
7
|
+
data.tar.gz: 51a5c6791429c17940d8d0a5407efb852fd4ddbe7a5eaf706dd8fb074a6654f17b32b08f21956e4e450dff6cff05fb0020a7ff8a141fe38f3e09b8433ca1b4ea
|
@@ -41,6 +41,14 @@ module Graphql
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
def module_namespacing_when_supported
|
45
|
+
if defined?(module_namespacing)
|
46
|
+
module_namespacing { yield }
|
47
|
+
else
|
48
|
+
yield
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
44
52
|
private
|
45
53
|
|
46
54
|
def schema_name
|
@@ -48,11 +56,19 @@ module Graphql
|
|
48
56
|
if options[:schema]
|
49
57
|
options[:schema]
|
50
58
|
else
|
51
|
-
|
52
|
-
"#{Rails.application.class.parent_name}Schema"
|
59
|
+
"#{parent_name}Schema"
|
53
60
|
end
|
54
61
|
end
|
55
62
|
end
|
63
|
+
|
64
|
+
def parent_name
|
65
|
+
require File.expand_path("config/application", destination_root)
|
66
|
+
if Rails.application.class.respond_to?(:module_parent_name)
|
67
|
+
Rails.application.class.module_parent_name
|
68
|
+
else
|
69
|
+
Rails.application.class.parent_name
|
70
|
+
end
|
71
|
+
end
|
56
72
|
end
|
57
73
|
end
|
58
74
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'rails/generators'
|
2
3
|
require 'rails/generators/base'
|
3
4
|
require_relative 'core'
|
5
|
+
require_relative 'relay'
|
4
6
|
|
5
7
|
module Graphql
|
6
8
|
module Generators
|
@@ -43,9 +45,6 @@ module Graphql
|
|
43
45
|
# post "/graphql", to: "graphql#execute"
|
44
46
|
# ```
|
45
47
|
#
|
46
|
-
# Accept a `--relay` option which adds
|
47
|
-
# The root `node(id: ID!)` field.
|
48
|
-
#
|
49
48
|
# Accept a `--batch` option which adds `GraphQL::Batch` setup.
|
50
49
|
#
|
51
50
|
# Use `--no-graphiql` to skip `graphiql-rails` installation.
|
@@ -53,6 +52,7 @@ module Graphql
|
|
53
52
|
# TODO: also add base classes
|
54
53
|
class InstallGenerator < Rails::Generators::Base
|
55
54
|
include Core
|
55
|
+
include Relay
|
56
56
|
|
57
57
|
desc "Install GraphQL folder structure and boilerplate code"
|
58
58
|
source_root File.expand_path('../templates', __FILE__)
|
@@ -79,14 +79,19 @@ module Graphql
|
|
79
79
|
|
80
80
|
class_option :relay,
|
81
81
|
type: :boolean,
|
82
|
-
default:
|
83
|
-
desc: "Include
|
82
|
+
default: true,
|
83
|
+
desc: "Include installation of Relay conventions (nodes, connections, edges)"
|
84
84
|
|
85
85
|
class_option :batch,
|
86
86
|
type: :boolean,
|
87
87
|
default: false,
|
88
88
|
desc: "Include GraphQL::Batch installation"
|
89
89
|
|
90
|
+
class_option :playground,
|
91
|
+
type: :boolean,
|
92
|
+
default: false,
|
93
|
+
desc: "Use GraphQL Playground over Graphiql as IDE"
|
94
|
+
|
90
95
|
# These two options are taken from Rails' own generators'
|
91
96
|
class_option :api,
|
92
97
|
type: :boolean,
|
@@ -117,7 +122,7 @@ module Graphql
|
|
117
122
|
if options.api?
|
118
123
|
say("Skipped graphiql, as this rails project is API only")
|
119
124
|
say(" You may wish to use GraphiQL.app for development: https://github.com/skevy/graphiql-app")
|
120
|
-
elsif !options[:skip_graphiql]
|
125
|
+
elsif !options[:skip_graphiql] && !File.read(Rails.root.join("Gemfile")).include?("graphiql-rails")
|
121
126
|
gem("graphiql-rails", group: :development)
|
122
127
|
|
123
128
|
# This is a little cheat just to get cleaner shell output:
|
@@ -140,6 +145,31 @@ RUBY
|
|
140
145
|
end
|
141
146
|
end
|
142
147
|
|
148
|
+
if options[:playground]
|
149
|
+
gem("graphql_playground-rails", group: :development)
|
150
|
+
|
151
|
+
log :route, 'graphql_playground-rails'
|
152
|
+
shell.mute do
|
153
|
+
if Rails::VERSION::STRING > "5.2"
|
154
|
+
route <<-RUBY
|
155
|
+
if Rails.env.development?
|
156
|
+
mount GraphqlPlayground::Rails::Engine, at: "/playground", graphql_path: "/graphql"
|
157
|
+
end
|
158
|
+
RUBY
|
159
|
+
else
|
160
|
+
route <<-RUBY
|
161
|
+
if Rails.env.development?
|
162
|
+
mount GraphqlPlayground::Rails::Engine, at: "/playground", graphql_path: "/graphql"
|
163
|
+
end
|
164
|
+
RUBY
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
if options[:relay]
|
170
|
+
install_relay
|
171
|
+
end
|
172
|
+
|
143
173
|
if gemfile_modified?
|
144
174
|
say "Gemfile has been modified, make sure you `bundle install`"
|
145
175
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'rails/generators'
|
2
3
|
require 'rails/generators/named_base'
|
3
4
|
require_relative 'core'
|
4
5
|
|
@@ -16,7 +17,7 @@ module Graphql
|
|
16
17
|
|
17
18
|
argument :name, type: :string
|
18
19
|
|
19
|
-
def initialize(args, *options)
|
20
|
+
def initialize(args, *options) # :nodoc:
|
20
21
|
# Unfreeze name in case it's given as a frozen string
|
21
22
|
args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
|
22
23
|
super
|
@@ -12,23 +12,68 @@ module Graphql
|
|
12
12
|
#
|
13
13
|
# Add the Node interface with `--node`.
|
14
14
|
class ObjectGenerator < TypeGeneratorBase
|
15
|
-
desc "Create a GraphQL::ObjectType with the given name and fields"
|
15
|
+
desc "Create a GraphQL::ObjectType with the given name and fields." \
|
16
|
+
"If the given type name matches an existing ActiveRecord model, the generated type will automatically include fields for the models database columns."
|
16
17
|
source_root File.expand_path('../templates', __FILE__)
|
17
18
|
|
18
|
-
argument :
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
argument :custom_fields,
|
20
|
+
type: :array,
|
21
|
+
default: [],
|
22
|
+
banner: "name:type name:type ...",
|
23
|
+
desc: "Fields for this object (type may be expressed as Ruby or GraphQL)"
|
23
24
|
|
24
25
|
class_option :node,
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
type: :boolean,
|
27
|
+
default: false,
|
28
|
+
desc: "Include the Relay Node interface"
|
28
29
|
|
29
30
|
def create_type_file
|
30
31
|
template "object.erb", "#{options[:directory]}/types/#{type_file_name}.rb"
|
31
32
|
end
|
33
|
+
|
34
|
+
def fields
|
35
|
+
columns = []
|
36
|
+
columns += klass.columns.map { |c| generate_column_string(c) } if class_exists?
|
37
|
+
columns + custom_fields
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.normalize_type_expression(type_expression, mode:, null: true)
|
41
|
+
case type_expression
|
42
|
+
when "Text"
|
43
|
+
["String", null]
|
44
|
+
when "Decimal"
|
45
|
+
["Float", null]
|
46
|
+
when "DateTime", "Datetime"
|
47
|
+
["GraphQL::Types::ISO8601DateTime", null]
|
48
|
+
when "Date"
|
49
|
+
["GraphQL::Types::ISO8601Date", null]
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def generate_column_string(column)
|
58
|
+
name = column.name
|
59
|
+
required = column.null ? "" : "!"
|
60
|
+
type = column_type_string(column)
|
61
|
+
"#{name}:#{required}#{type}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def column_type_string(column)
|
65
|
+
column.name == "id" ? "ID" : column.type.to_s.camelize
|
66
|
+
end
|
67
|
+
|
68
|
+
def class_exists?
|
69
|
+
klass.is_a?(Class) && klass.ancestors.include?(ActiveRecord::Base)
|
70
|
+
rescue NameError
|
71
|
+
return false
|
72
|
+
end
|
73
|
+
|
74
|
+
def klass
|
75
|
+
@klass ||= Module.const_get(type_name.camelize)
|
76
|
+
end
|
32
77
|
end
|
33
78
|
end
|
34
79
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Graphql
|
3
|
+
module Generators
|
4
|
+
module Relay
|
5
|
+
def install_relay
|
6
|
+
# Add Node, `node(id:)`, and `nodes(ids:)`
|
7
|
+
template("node_type.erb", "#{options[:directory]}/types/node_type.rb")
|
8
|
+
in_root do
|
9
|
+
fields = " # Add `node(id: ID!) and `nodes(ids: [ID!]!)`\n include GraphQL::Types::Relay::HasNodeField\n include GraphQL::Types::Relay::HasNodesField\n\n"
|
10
|
+
inject_into_file "#{options[:directory]}/types/query_type.rb", fields, after: /class .*QueryType\s*<\s*[^\s]+?\n/m, force: false
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add connections and edges
|
14
|
+
template("base_connection.erb", "#{options[:directory]}/types/base_connection.rb")
|
15
|
+
template("base_edge.erb", "#{options[:directory]}/types/base_edge.rb")
|
16
|
+
connectionable_type_files = {
|
17
|
+
"#{options[:directory]}/types/base_object.rb" => /class .*BaseObject\s*<\s*[^\s]+?\n/m,
|
18
|
+
"#{options[:directory]}/types/base_union.rb" => /class .*BaseUnion\s*<\s*[^\s]+?\n/m,
|
19
|
+
"#{options[:directory]}/types/base_interface.rb" => /include GraphQL::Schema::Interface\n/m,
|
20
|
+
}
|
21
|
+
in_root do
|
22
|
+
connectionable_type_files.each do |type_class_file, sentinel|
|
23
|
+
inject_into_file type_class_file, " connection_type_class(Types::BaseConnection)\n", after: sentinel, force: false
|
24
|
+
inject_into_file type_class_file, " edge_type_class(Types::BaseEdge)\n", after: sentinel, force: false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add object ID hooks & connection plugin
|
29
|
+
schema_code = <<-RUBY
|
30
|
+
|
31
|
+
# Relay-style Object Identification:
|
32
|
+
|
33
|
+
# Return a string UUID for `object`
|
34
|
+
def self.id_from_object(object, type_definition, query_ctx)
|
35
|
+
# For example, use Rails' GlobalID library (https://github.com/rails/globalid):
|
36
|
+
object_id = object.to_global_id.to_s
|
37
|
+
# Remove this redundant prefix to make IDs shorter:
|
38
|
+
object_id = object_id.sub("gid://\#{GlobalID.app}/", "")
|
39
|
+
encoded_id = Base64.urlsafe_encode64(object_id)
|
40
|
+
# Remove the "=" padding
|
41
|
+
encoded_id = encoded_id.sub(/=+/, "")
|
42
|
+
# Add a type hint
|
43
|
+
type_hint = type_definition.graphql_name.first
|
44
|
+
"\#{type_hint}_\#{encoded_id}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Given a string UUID, find the object
|
48
|
+
def self.object_from_id(encoded_id_with_hint, query_ctx)
|
49
|
+
# For example, use Rails' GlobalID library (https://github.com/rails/globalid):
|
50
|
+
# Split off the type hint
|
51
|
+
_type_hint, encoded_id = encoded_id_with_hint.split("_", 2)
|
52
|
+
# Decode the ID
|
53
|
+
id = Base64.urlsafe_decode64(encoded_id)
|
54
|
+
# Rebuild it for Rails then find the object:
|
55
|
+
full_global_id = "gid://\#{GlobalID.app}/\#{id}"
|
56
|
+
GlobalID::Locator.locate(full_global_id)
|
57
|
+
end
|
58
|
+
RUBY
|
59
|
+
inject_into_file schema_file_path, schema_code, before: /^end\n/m, force: false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rails/generators'
|
3
|
+
require 'rails/generators/base'
|
4
|
+
require_relative 'core'
|
5
|
+
require_relative 'relay'
|
6
|
+
|
7
|
+
module Graphql
|
8
|
+
module Generators
|
9
|
+
class RelayGenerator < Rails::Generators::Base
|
10
|
+
include Core
|
11
|
+
include Relay
|
12
|
+
|
13
|
+
desc "Add base types and fields for Relay-style nodes and connections"
|
14
|
+
source_root File.expand_path('../templates', __FILE__)
|
15
|
+
|
16
|
+
def install_relay
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
2
|
+
module Types
|
3
|
+
class BaseConnection < Types::BaseObject
|
4
|
+
# add `nodes` and `pageInfo` fields, as well as `edge_type(...)` and `node_nullable(...)` overrides
|
5
|
+
include GraphQL::Types::Relay::ConnectionBehaviors
|
6
|
+
end
|
7
|
+
end
|
8
|
+
<% end -%>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
1
2
|
class GraphqlController < ApplicationController
|
2
3
|
# If accessing from outside this domain, nullify the session
|
3
4
|
# This allows for outside API access while preventing CSRF attacks,
|
@@ -5,7 +6,7 @@ class GraphqlController < ApplicationController
|
|
5
6
|
# protect_from_forgery with: :null_session
|
6
7
|
|
7
8
|
def execute
|
8
|
-
variables =
|
9
|
+
variables = prepare_variables(params[:variables])
|
9
10
|
query = params[:query]
|
10
11
|
operation_name = params[:operationName]
|
11
12
|
context = {
|
@@ -14,28 +15,30 @@ class GraphqlController < ApplicationController
|
|
14
15
|
}
|
15
16
|
result = <%= schema_name %>.execute(query, variables: variables, context: context, operation_name: operation_name)
|
16
17
|
render json: result
|
17
|
-
rescue => e
|
18
|
+
rescue StandardError => e
|
18
19
|
raise e unless Rails.env.development?
|
19
|
-
handle_error_in_development
|
20
|
+
handle_error_in_development(e)
|
20
21
|
end
|
21
22
|
|
22
23
|
private
|
23
24
|
|
24
|
-
# Handle form data, JSON body, or a blank value
|
25
|
-
def
|
26
|
-
case
|
25
|
+
# Handle variables in form data, JSON body, or a blank value
|
26
|
+
def prepare_variables(variables_param)
|
27
|
+
case variables_param
|
27
28
|
when String
|
28
|
-
if
|
29
|
-
|
29
|
+
if variables_param.present?
|
30
|
+
JSON.parse(variables_param) || {}
|
30
31
|
else
|
31
32
|
{}
|
32
33
|
end
|
33
|
-
when Hash
|
34
|
-
|
34
|
+
when Hash
|
35
|
+
variables_param
|
36
|
+
when ActionController::Parameters
|
37
|
+
variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables.
|
35
38
|
when nil
|
36
39
|
{}
|
37
40
|
else
|
38
|
-
raise ArgumentError, "Unexpected parameter: #{
|
41
|
+
raise ArgumentError, "Unexpected parameter: #{variables_param}"
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
@@ -43,6 +46,7 @@ class GraphqlController < ApplicationController
|
|
43
46
|
logger.error e.message
|
44
47
|
logger.error e.backtrace.join("\n")
|
45
48
|
|
46
|
-
render json: {
|
49
|
+
render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} }, status: 500
|
47
50
|
end
|
48
51
|
end
|
52
|
+
<% end -%>
|
@@ -1,6 +1,8 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
1
2
|
module Types
|
2
3
|
class <%= type_ruby_name.split('::')[-1] %> < Types::BaseObject
|
3
|
-
<% if options.node %> implements GraphQL::Relay::Node
|
4
|
+
<% if options.node %> implements GraphQL::Types::Relay::Node
|
4
5
|
<% end %><% normalized_fields.each do |f| %> <%= f.to_ruby %>
|
5
6
|
<% end %> end
|
6
7
|
end
|
8
|
+
<% end -%>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
1
2
|
module Types
|
2
3
|
class QueryType < Types::BaseObject
|
3
4
|
# Add root-level fields here.
|
@@ -9,7 +10,6 @@ module Types
|
|
9
10
|
def test_field
|
10
11
|
"Hello World!"
|
11
12
|
end
|
12
|
-
|
13
|
-
field :node, field: GraphQL::Relay::Node.field
|
14
|
-
<% end %> end
|
13
|
+
end
|
15
14
|
end
|
15
|
+
<% end -%>
|
@@ -1,39 +1,27 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
1
2
|
class <%= schema_name %> < GraphQL::Schema
|
2
3
|
query(Types::QueryType)
|
3
|
-
|
4
|
-
#
|
5
|
-
use GraphQL::
|
6
|
-
|
7
|
-
#
|
8
|
-
use GraphQL::
|
9
|
-
<%
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
# GraphQL::Schema::UniqueWithinType.encode(type_definition.name, object.id)
|
18
|
-
end
|
19
|
-
|
20
|
-
# Given a string UUID, find the object
|
21
|
-
def self.object_from_id(id, query_ctx)
|
22
|
-
# For example, to decode the UUIDs generated above:
|
23
|
-
# type_name, item_id = GraphQL::Schema::UniqueWithinType.decode(id)
|
24
|
-
#
|
25
|
-
# Then, based on `type_name` and `id`
|
26
|
-
# find an object in your application
|
27
|
-
# ...
|
4
|
+
<% if options[:batch] %>
|
5
|
+
# GraphQL::Batch setup:
|
6
|
+
use GraphQL::Batch
|
7
|
+
<% else %>
|
8
|
+
# For batch-loading (see https://graphql-ruby.org/dataloader/overview.html)
|
9
|
+
use GraphQL::Dataloader
|
10
|
+
<% end %>
|
11
|
+
# GraphQL-Ruby calls this when something goes wrong while running a query:
|
12
|
+
def self.type_error(err, context)
|
13
|
+
# if err.is_a?(GraphQL::InvalidNullError)
|
14
|
+
# # report to your bug tracker here
|
15
|
+
# return nil
|
16
|
+
# end
|
17
|
+
super
|
28
18
|
end
|
29
19
|
|
30
|
-
#
|
31
|
-
def self.resolve_type(
|
32
|
-
# TODO: Implement this
|
33
|
-
# to return the correct type for `obj`
|
20
|
+
# Union and Interface Resolution
|
21
|
+
def self.resolve_type(abstract_type, obj, ctx)
|
22
|
+
# TODO: Implement this method
|
23
|
+
# to return the correct GraphQL object type for `obj`
|
34
24
|
raise(GraphQL::RequiredImplementationMissingError)
|
35
25
|
end
|
36
|
-
|
37
|
-
|
38
|
-
use GraphQL::Batch
|
39
|
-
<% end %>end
|
26
|
+
end
|
27
|
+
<% end -%>
|
@@ -1,5 +1,7 @@
|
|
1
|
+
<% module_namespacing_when_supported do -%>
|
1
2
|
module Types
|
2
3
|
class <%= type_ruby_name.split('::')[-1] %> < Types::BaseUnion
|
3
|
-
<% if possible_types.any? %> possible_types
|
4
|
+
<% if possible_types.any? %> possible_types <%= normalized_possible_types.join(", ") %>
|
4
5
|
<% end %> end
|
5
6
|
end
|
7
|
+
<% end -%>
|