graphql 1.6.4 → 1.6.5
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/core.rb +47 -0
- data/lib/generators/graphql/install_generator.rb +15 -20
- data/lib/generators/graphql/mutation_generator.rb +31 -1
- data/lib/generators/graphql/templates/mutation.erb +2 -2
- data/lib/generators/graphql/templates/mutation_type.erb +5 -0
- data/lib/generators/graphql/templates/schema.erb +0 -1
- data/lib/graphql/argument.rb +6 -5
- data/lib/graphql/backwards_compatibility.rb +18 -4
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -1
- data/lib/graphql/compatibility/lazy_execution_specification.rb +9 -2
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/no_definition_error.rb +7 -0
- data/lib/graphql/enum_type.rb +4 -0
- data/lib/graphql/execution/execute.rb +3 -3
- data/lib/graphql/execution/field_result.rb +1 -1
- data/lib/graphql/execution/lazy/resolve.rb +10 -9
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/input_object_type.rb +5 -1
- data/lib/graphql/interface_type.rb +12 -3
- data/lib/graphql/query.rb +21 -5
- data/lib/graphql/query/context.rb +11 -0
- data/lib/graphql/schema.rb +48 -27
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/traversal.rb +91 -0
- data/lib/graphql/schema/validation.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -7
- data/lib/graphql/union_type.rb +13 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -3
- data/spec/generators/graphql/install_generator_spec.rb +3 -1
- data/spec/generators/graphql/mutation_generator_spec.rb +14 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +12 -1
- data/spec/graphql/analysis/query_complexity_spec.rb +1 -1
- data/spec/graphql/argument_spec.rb +29 -0
- data/spec/graphql/define/assign_argument_spec.rb +4 -4
- data/spec/graphql/define/instance_definable_spec.rb +1 -1
- data/spec/graphql/enum_type_spec.rb +8 -0
- data/spec/graphql/execution/lazy_spec.rb +30 -3
- data/spec/graphql/interface_type_spec.rb +44 -0
- data/spec/graphql/introspection/schema_type_spec.rb +3 -0
- data/spec/graphql/introspection/type_type_spec.rb +1 -0
- data/spec/graphql/object_type_spec.rb +8 -3
- data/spec/graphql/query/context_spec.rb +18 -0
- data/spec/graphql/query/executor_spec.rb +1 -1
- data/spec/graphql/query/literal_input_spec.rb +31 -15
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
- data/spec/graphql/query/variables_spec.rb +25 -1
- data/spec/graphql/query_spec.rb +24 -9
- data/spec/graphql/relay/mutation_spec.rb +1 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +1 -1
- data/spec/graphql/schema/loader_spec.rb +1 -1
- data/spec/graphql/schema/printer_spec.rb +1 -1
- data/spec/graphql/schema/{reduce_types_spec.rb → traversal_spec.rb} +21 -4
- data/spec/graphql/schema/warden_spec.rb +1 -1
- data/spec/graphql/schema_spec.rb +23 -2
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +133 -0
- data/spec/graphql/union_type_spec.rb +53 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/dummy/data.rb +14 -5
- data/spec/support/dummy/schema.rb +46 -5
- data/spec/support/star_wars/data.rb +10 -6
- data/spec/support/star_wars/schema.rb +5 -2
- metadata +8 -7
- data/lib/graphql/schema/instrumented_field_map.rb +0 -40
- data/lib/graphql/schema/reduce_types.rb +0 -69
- data/lib/graphql/schema/type_map.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a043673bcabc1f7cbcc834d71919a4a61dd36a6a
|
4
|
+
data.tar.gz: efc89423aa48aecce87434a1f0e4567fdf4de290
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d379a08ef187cef29cec03dfb570d3064bc762ff117a5f4e912ef2b5e4cd6f512f1317b42a1e0ae5ccb0510eb505ab36e0ef8ff61c7331326523b7d49889d7d7
|
7
|
+
data.tar.gz: 58ddefe960ea3e4d75d9c55ba06403632974a796f6fa5a3869977b2733d5dad17e0037390848cdd738b605b89e22807e47508d64a03f4c8978f46d714cc393f0
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rails/generators/base'
|
3
|
+
|
4
|
+
module Graphql
|
5
|
+
module Generators
|
6
|
+
module Core
|
7
|
+
def insert_root_type(type, name)
|
8
|
+
log :add_root_type, type
|
9
|
+
sentinel = /GraphQL\:\:Schema\.define do\s*\n/m
|
10
|
+
|
11
|
+
in_root do
|
12
|
+
inject_into_file schema_file_path, " #{type}(Types::#{name})\n", after: sentinel, verbose: false, force: false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_mutation_root_type
|
17
|
+
create_dir("app/graphql/mutations")
|
18
|
+
template("mutation_type.erb", "app/graphql/types/mutation_type.rb", { skip: true })
|
19
|
+
insert_root_type('mutation', 'MutationType')
|
20
|
+
end
|
21
|
+
|
22
|
+
def schema_file_path
|
23
|
+
"app/graphql/#{schema_name.underscore}.rb"
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_dir(dir)
|
27
|
+
empty_directory(dir)
|
28
|
+
if !options[:skip_keeps]
|
29
|
+
create_file("#{dir}/.keep")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def schema_name
|
36
|
+
@schema_name ||= begin
|
37
|
+
if options[:schema]
|
38
|
+
options[:schema]
|
39
|
+
else
|
40
|
+
require File.expand_path("config/application", destination_root)
|
41
|
+
"#{Rails.application.class.parent_name}Schema"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'rails/generators/base'
|
3
|
+
require_relative 'core'
|
3
4
|
|
4
5
|
module Graphql
|
5
6
|
module Generators
|
@@ -40,6 +41,8 @@ module Graphql
|
|
40
41
|
#
|
41
42
|
# Use `--no-graphiql` to skip `graphiql-rails` installation.
|
42
43
|
class InstallGenerator < Rails::Generators::Base
|
44
|
+
include Core
|
45
|
+
|
43
46
|
desc "Install GraphQL folder structure and boilerplate code"
|
44
47
|
source_root File.expand_path('../templates', __FILE__)
|
45
48
|
|
@@ -58,6 +61,11 @@ module Graphql
|
|
58
61
|
default: false,
|
59
62
|
desc: "Skip graphiql-rails installation"
|
60
63
|
|
64
|
+
class_option :skip_mutation_root_type,
|
65
|
+
type: :boolean,
|
66
|
+
default: false,
|
67
|
+
desc: "Skip creation of the mutation root type"
|
68
|
+
|
61
69
|
class_option :relay,
|
62
70
|
type: :boolean,
|
63
71
|
default: false,
|
@@ -81,10 +89,15 @@ if Rails.env.development?
|
|
81
89
|
RUBY
|
82
90
|
|
83
91
|
def create_folder_structure
|
84
|
-
create_dir("app/graphql/mutations")
|
85
92
|
create_dir("app/graphql/types")
|
93
|
+
template("schema.erb", schema_file_path)
|
94
|
+
|
95
|
+
# Note: Yuo can't have a schema without the query type, otherwise introspection breaks
|
86
96
|
template("query_type.erb", "app/graphql/types/query_type.rb")
|
87
|
-
|
97
|
+
insert_root_type('query', 'QueryType')
|
98
|
+
|
99
|
+
create_mutation_root_type unless options.skip_mutation_root_type?
|
100
|
+
|
88
101
|
template("graphql_controller.erb", "app/controllers/graphql_controller.rb")
|
89
102
|
route('post "/graphql", to: "graphql#execute"')
|
90
103
|
|
@@ -121,24 +134,6 @@ RUBY
|
|
121
134
|
@gemfile_modified = true
|
122
135
|
super(*args)
|
123
136
|
end
|
124
|
-
|
125
|
-
def create_dir(dir)
|
126
|
-
empty_directory(dir)
|
127
|
-
if !options[:skip_keeps]
|
128
|
-
create_file("#{dir}/.keep")
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def schema_name
|
133
|
-
@schema_name ||= begin
|
134
|
-
if options[:schema]
|
135
|
-
options[:schema]
|
136
|
-
else
|
137
|
-
require File.expand_path("config/application", destination_root)
|
138
|
-
"#{Rails.application.class.parent_name}Schema"
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
137
|
end
|
143
138
|
end
|
144
139
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'rails/generators/named_base'
|
3
|
+
require_relative 'core'
|
3
4
|
|
4
5
|
module Graphql
|
5
6
|
module Generators
|
@@ -7,12 +8,41 @@ module Graphql
|
|
7
8
|
#
|
8
9
|
# @example Generate a `Relay::Mutation` by name
|
9
10
|
# rails g graphql:mutation CreatePostMutation
|
10
|
-
class MutationGenerator < Rails::Generators::
|
11
|
+
class MutationGenerator < Rails::Generators::Base
|
12
|
+
include Core
|
13
|
+
|
11
14
|
desc "Create a Relay mutation by name"
|
12
15
|
source_root File.expand_path('../templates', __FILE__)
|
13
16
|
|
17
|
+
argument :name, type: :string
|
18
|
+
|
19
|
+
def initialize(args, *options) #:nodoc:
|
20
|
+
# Unfreeze name in case it's given as a frozen string
|
21
|
+
args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
|
22
|
+
super
|
23
|
+
|
24
|
+
assign_names!(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :file_name, :mutation_name, :field_name
|
28
|
+
|
14
29
|
def create_mutation_file
|
30
|
+
create_mutation_root_type
|
15
31
|
template "mutation.erb", "app/graphql/mutations/#{file_name}.rb"
|
32
|
+
|
33
|
+
sentinel = /name "Mutation"\s*\n/m
|
34
|
+
in_root do
|
35
|
+
gsub_file "app/graphql/types/mutation_type.rb", / \# TODO\: Add Mutations as fields\s*\n/m, ""
|
36
|
+
inject_into_file "app/graphql/types/mutation_type.rb", " field :#{field_name}, Mutations::#{mutation_name}.field\n", after: sentinel, verbose: false, force: false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def assign_names!(name)
|
43
|
+
@field_name = name.camelize(:lower)
|
44
|
+
@mutation_name = name.camelize(:upper)
|
45
|
+
@file_name = name.camelize.underscore
|
16
46
|
end
|
17
47
|
end
|
18
48
|
end
|
data/lib/graphql/argument.rb
CHANGED
@@ -96,11 +96,11 @@ module GraphQL
|
|
96
96
|
|
97
97
|
NO_DEFAULT_VALUE = Object.new
|
98
98
|
# @api private
|
99
|
-
def self.from_dsl(name, type = nil, description = nil, default_value: NO_DEFAULT_VALUE, as: nil, prepare: DefaultPrepare, &block)
|
99
|
+
def self.from_dsl(name, type = nil, description = nil, default_value: NO_DEFAULT_VALUE, as: nil, prepare: DefaultPrepare, **kwargs, &block)
|
100
100
|
argument = if block_given?
|
101
101
|
GraphQL::Argument.define(&block)
|
102
102
|
else
|
103
|
-
GraphQL::Argument.
|
103
|
+
GraphQL::Argument.define(**kwargs)
|
104
104
|
end
|
105
105
|
|
106
106
|
argument.name = name.to_s
|
@@ -109,9 +109,10 @@ module GraphQL
|
|
109
109
|
if default_value != NO_DEFAULT_VALUE
|
110
110
|
argument.default_value = default_value
|
111
111
|
end
|
112
|
-
argument.as = as
|
113
|
-
|
114
|
-
|
112
|
+
as && argument.as = as
|
113
|
+
if prepare != DefaultPrepare
|
114
|
+
argument.prepare = prepare
|
115
|
+
end
|
115
116
|
|
116
117
|
argument
|
117
118
|
end
|
@@ -8,7 +8,9 @@ module GraphQL
|
|
8
8
|
# check its arity, and if needed, apply a wrapper so that
|
9
9
|
# it can be called with `to` arguments.
|
10
10
|
# If a wrapper is applied, warn the application with `name`.
|
11
|
-
|
11
|
+
#
|
12
|
+
# If `last`, then use the last arguments to call the function.
|
13
|
+
def wrap_arity(callable, from:, to:, name:, last: false)
|
12
14
|
arity = get_arity(callable)
|
13
15
|
case arity
|
14
16
|
when to
|
@@ -16,8 +18,13 @@ module GraphQL
|
|
16
18
|
callable
|
17
19
|
when from
|
18
20
|
# It has the old arity, so wrap it with an arity converter
|
19
|
-
|
20
|
-
|
21
|
+
message ="#{name} with #{from} arguments is deprecated, it now accepts #{to} arguments, see:"
|
22
|
+
backtrace = caller(0, 20)
|
23
|
+
# Find the first line in the trace that isn't library internals:
|
24
|
+
user_line = backtrace.find {|l| l !~ /lib\/graphql/ }
|
25
|
+
warn(message + "\n" + user_line + "\n")
|
26
|
+
wrapper = last ? LastArgumentsWrapper : FirstArgumentsWrapper
|
27
|
+
wrapper.new(callable, from)
|
21
28
|
else
|
22
29
|
raise "Can't wrap #{callable} (arity: #{arity}) to have arity #{to}"
|
23
30
|
end
|
@@ -32,7 +39,7 @@ module GraphQL
|
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
35
|
-
class
|
42
|
+
class FirstArgumentsWrapper
|
36
43
|
def initialize(callable, old_arity)
|
37
44
|
@callable = callable
|
38
45
|
@old_arity = old_arity
|
@@ -43,5 +50,12 @@ module GraphQL
|
|
43
50
|
@callable.call(*backwards_compat_args)
|
44
51
|
end
|
45
52
|
end
|
53
|
+
|
54
|
+
class LastArgumentsWrapper < FirstArgumentsWrapper
|
55
|
+
def call(*args)
|
56
|
+
backwards_compat_args = args.last(@old_arity)
|
57
|
+
@callable.call(*backwards_compat_args)
|
58
|
+
end
|
59
|
+
end
|
46
60
|
end
|
47
61
|
end
|
data/lib/graphql/base_type.rb
CHANGED
@@ -40,7 +40,7 @@ module GraphQL
|
|
40
40
|
|
41
41
|
schema = GraphQL::Schema.define(
|
42
42
|
query: query_type,
|
43
|
-
resolve_type: ->(o, c) { o == :counter ? counter_type : nil },
|
43
|
+
resolve_type: ->(t, o, c) { o == :counter ? counter_type : nil },
|
44
44
|
orphan_types: [alt_counter_type, counter_type],
|
45
45
|
query_execution_strategy: execution_strategy,
|
46
46
|
)
|
@@ -24,11 +24,17 @@ module GraphQL
|
|
24
24
|
p2: push(value: 2) {
|
25
25
|
push(value: 3) {
|
26
26
|
value
|
27
|
+
push(value: 21) {
|
28
|
+
value
|
29
|
+
}
|
27
30
|
}
|
28
31
|
}
|
29
32
|
p3: push(value: 4) {
|
30
33
|
push(value: 5) {
|
31
34
|
value
|
35
|
+
push(value: 22) {
|
36
|
+
value
|
37
|
+
}
|
32
38
|
}
|
33
39
|
}
|
34
40
|
}
|
@@ -37,14 +43,15 @@ module GraphQL
|
|
37
43
|
|
38
44
|
expected_data = {
|
39
45
|
"p1"=>{"value"=>1},
|
40
|
-
"p2"=>{"push"=>{"value"=>3}},
|
41
|
-
"p3"=>{"push"=>{"value"=>5}},
|
46
|
+
"p2"=>{"push"=>{"value"=>3, "push"=>{"value"=>21}}},
|
47
|
+
"p3"=>{"push"=>{"value"=>5, "push"=>{"value"=>22}}},
|
42
48
|
}
|
43
49
|
assert_equal expected_data, res["data"]
|
44
50
|
|
45
51
|
expected_pushes = [
|
46
52
|
[1,2,4], # first level
|
47
53
|
[3,5], # second level
|
54
|
+
[21, 22],
|
48
55
|
]
|
49
56
|
assert_equal expected_pushes, pushes
|
50
57
|
end
|
data/lib/graphql/define.rb
CHANGED
@@ -7,6 +7,7 @@ require "graphql/define/assign_mutation_function"
|
|
7
7
|
require "graphql/define/assign_object_field"
|
8
8
|
require "graphql/define/defined_object_proxy"
|
9
9
|
require "graphql/define/instance_definable"
|
10
|
+
require "graphql/define/no_definition_error"
|
10
11
|
require "graphql/define/non_null_with_bang"
|
11
12
|
require "graphql/define/type_definer"
|
12
13
|
|
data/lib/graphql/enum_type.rb
CHANGED
@@ -93,6 +93,10 @@ module GraphQL
|
|
93
93
|
|
94
94
|
# @param enum_value [EnumValue] A value to add to this type's set of values
|
95
95
|
def add_value(enum_value)
|
96
|
+
if @values_by_name.key?(enum_value.name)
|
97
|
+
raise "Enum value names must be unique. `#{enum_value.name}` already exists."
|
98
|
+
end
|
99
|
+
|
96
100
|
@values_by_name[enum_value.name] = enum_value
|
97
101
|
end
|
98
102
|
|
@@ -76,8 +76,8 @@ module GraphQL
|
|
76
76
|
selection: selection,
|
77
77
|
)
|
78
78
|
|
79
|
-
arguments = query.arguments_for(selection, field)
|
80
79
|
raw_value = begin
|
80
|
+
arguments = query.arguments_for(selection, field)
|
81
81
|
query_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
|
82
82
|
rescue GraphQL::ExecutionError => err
|
83
83
|
err
|
@@ -116,7 +116,7 @@ module GraphQL
|
|
116
116
|
|
117
117
|
case raw_value
|
118
118
|
when GraphQL::ExecutionError
|
119
|
-
raw_value.ast_node
|
119
|
+
raw_value.ast_node ||= field_ctx.ast_node
|
120
120
|
raw_value.path = field_ctx.path
|
121
121
|
query.context.errors.push(raw_value)
|
122
122
|
when Array
|
@@ -210,7 +210,7 @@ module GraphQL
|
|
210
210
|
)
|
211
211
|
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
212
212
|
query = field_ctx.query
|
213
|
-
resolved_type =
|
213
|
+
resolved_type = field_type.resolve_type(value, field_ctx)
|
214
214
|
possible_types = query.possible_types(field_type)
|
215
215
|
|
216
216
|
if !possible_types.include?(resolved_type)
|
@@ -35,14 +35,14 @@ module GraphQL
|
|
35
35
|
if acc.empty?
|
36
36
|
Lazy::NullResult
|
37
37
|
else
|
38
|
-
|
39
|
-
acc
|
38
|
+
Lazy.new {
|
39
|
+
acc.each_with_index { |field_result, idx|
|
40
|
+
inner_v = field_result.value.value
|
40
41
|
field_result.value = inner_v
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
Lazy.new { acc.each_with_index { |l, idx| acc[idx] = l.value }; acc }
|
42
|
+
acc[idx] = inner_v
|
43
|
+
}
|
44
|
+
resolve_in_place(acc)
|
45
|
+
}
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -62,9 +62,10 @@ module GraphQL
|
|
62
62
|
end
|
63
63
|
when FieldResult
|
64
64
|
field_value = value.value
|
65
|
-
|
65
|
+
case field_value
|
66
|
+
when Lazy
|
66
67
|
acc = acc << value
|
67
|
-
|
68
|
+
when SelectionResult
|
68
69
|
acc = each_lazy(acc, field_value)
|
69
70
|
end
|
70
71
|
end
|