graphql 1.8.7 → 1.8.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/enum_type.rb +4 -0
- data/lib/graphql/execution/multiplex.rb +1 -1
- data/lib/graphql/schema/argument.rb +1 -0
- data/lib/graphql/schema/enum_value.rb +1 -0
- data/lib/graphql/schema/field.rb +1 -0
- data/lib/graphql/schema/interface.rb +1 -0
- data/lib/graphql/schema/member.rb +2 -0
- data/lib/graphql/schema/member/has_path.rb +25 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +3 -9
- data/lib/graphql/schema/resolver.rb +25 -5
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +21 -2
- data/lib/graphql/upgrader/member.rb +5 -0
- data/lib/graphql/version.rb +1 -1
- data/spec/dummy/Gemfile +1 -1
- data/spec/graphql/enum_type_spec.rb +5 -0
- data/spec/graphql/execution/execute_spec.rb +1 -1
- data/spec/graphql/execution/multiplex_spec.rb +28 -1
- data/spec/graphql/internal_representation/rewrite_spec.rb +2 -0
- data/spec/graphql/schema/argument_spec.rb +5 -1
- data/spec/graphql/schema/enum_spec.rb +7 -0
- data/spec/graphql/schema/enum_value_spec.rb +11 -0
- data/spec/graphql/schema/field_spec.rb +7 -0
- data/spec/graphql/schema/input_object_spec.rb +11 -0
- data/spec/graphql/schema/interface_spec.rb +6 -0
- data/spec/graphql/schema/object_spec.rb +6 -0
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +71 -0
- data/spec/graphql/schema/resolver_spec.rb +72 -8
- data/spec/graphql/schema/scalar_spec.rb +6 -0
- data/spec/graphql/schema/union_spec.rb +7 -0
- data/spec/graphql/upgrader/member_spec.rb +67 -0
- data/spec/{graphql → integration/mongoid/graphql}/relay/mongo_relation_connection_spec.rb +0 -11
- data/spec/integration/mongoid/spec_helper.rb +2 -0
- data/spec/{support → integration/mongoid}/star_trek/data.rb +0 -0
- data/spec/{support → integration/mongoid}/star_trek/schema.rb +0 -0
- data/spec/{support/star_wars → integration/rails}/data.rb +1 -0
- data/spec/{support → integration/rails/generators}/base_generator_test.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/enum_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/install_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/interface_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/loader_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/mutation_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/object_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/union_generator_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/input_object_type_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/query/variables_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/array_connection_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/base_connection_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/connection_instrumentation_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/connection_resolve_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/connection_type_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/edge_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/mutation_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/node_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/page_info_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/range_add_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/relation_connection_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/schema_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/tracing/active_support_notifications_tracing_spec.rb +0 -0
- data/spec/integration/rails/spec_helper.rb +15 -0
- data/spec/spec_helper.rb +16 -39
- data/spec/support/jazz.rb +48 -0
- metadata +260 -243
- data/spec/rails_dependency_sanity_spec.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8642c253947a56246003a995f373e3088b70848
|
4
|
+
data.tar.gz: 0e027e906d12ff726e144220849ac216b66dc56d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfabff78ee8e8bb710ee73bfcb191d7b040a55eb042a2b94cf8d8d3169671b954aa13901c095124a516d593f49d21f1c9f2f63ed2731308e77e74fbffad9d726
|
7
|
+
data.tar.gz: d924393eea98ab77207c0fa35abc579373f650000e66b82cd181f1e5286b58d8794e29fcc4f3796f3b8db6f0dec0c7293e8244275cdceb0f45f39bde556f8f89
|
data/lib/graphql/enum_type.rb
CHANGED
data/lib/graphql/schema/field.rb
CHANGED
@@ -6,6 +6,7 @@ module GraphQL
|
|
6
6
|
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
7
7
|
include GraphQL::Schema::Member::AcceptsDefinition
|
8
8
|
include GraphQL::Schema::Member::HasArguments
|
9
|
+
include GraphQL::Schema::Member::HasPath
|
9
10
|
|
10
11
|
# @return [String] the GraphQL name for this field, camelized unless `camelize: false` is provided
|
11
12
|
attr_reader :name
|
@@ -9,6 +9,7 @@ module GraphQL
|
|
9
9
|
include GraphQL::Schema::Member::BaseDSLMethods
|
10
10
|
include GraphQL::Schema::Member::TypeSystemHelpers
|
11
11
|
include GraphQL::Schema::Member::HasFields
|
12
|
+
include GraphQL::Schema::Member::HasPath
|
12
13
|
include GraphQL::Schema::Member::RelayShortcuts
|
13
14
|
include GraphQL::Schema::Member::Scoped
|
14
15
|
|
@@ -3,6 +3,7 @@ require 'graphql/schema/member/accepts_definition'
|
|
3
3
|
require 'graphql/schema/member/base_dsl_methods'
|
4
4
|
require 'graphql/schema/member/cached_graphql_definition'
|
5
5
|
require 'graphql/schema/member/graphql_type_names'
|
6
|
+
require 'graphql/schema/member/has_path'
|
6
7
|
require 'graphql/schema/member/relay_shortcuts'
|
7
8
|
require 'graphql/schema/member/scoped'
|
8
9
|
require 'graphql/schema/member/type_system_helpers'
|
@@ -22,6 +23,7 @@ module GraphQL
|
|
22
23
|
extend TypeSystemHelpers
|
23
24
|
extend Scoped
|
24
25
|
extend RelayShortcuts
|
26
|
+
extend HasPath
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
module HasPath
|
7
|
+
# @return [String] A description of this member's place in the GraphQL schema
|
8
|
+
def path
|
9
|
+
path_str = if self.respond_to?(:graphql_name)
|
10
|
+
self.graphql_name
|
11
|
+
elsif self.class.respond_to?(:graphql_name)
|
12
|
+
# Instances of resolvers
|
13
|
+
self.class.graphql_name
|
14
|
+
end
|
15
|
+
|
16
|
+
if self.respond_to?(:owner) && owner.respond_to?(:path)
|
17
|
+
path_str = "#{owner.path}.#{path_str}"
|
18
|
+
end
|
19
|
+
|
20
|
+
path_str
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -25,20 +25,14 @@ module GraphQL
|
|
25
25
|
# Relay classic default:
|
26
26
|
null(true)
|
27
27
|
|
28
|
-
# Override {GraphQL::Schema::
|
28
|
+
# Override {GraphQL::Schema::Resolver#resolve_with_support} to
|
29
29
|
# delete `client_mutation_id` from the kwargs.
|
30
|
-
def
|
30
|
+
def resolve_with_support(**kwargs)
|
31
31
|
# This is handled by Relay::Mutation::Resolve, a bit hacky, but here we are.
|
32
32
|
kwargs.delete(:client_mutation_id)
|
33
|
-
|
34
|
-
resolve(**kwargs)
|
35
|
-
else
|
36
|
-
resolve
|
37
|
-
end
|
33
|
+
super
|
38
34
|
end
|
39
35
|
|
40
|
-
resolve_method(:resolve_mutation)
|
41
|
-
|
42
36
|
class << self
|
43
37
|
# The base class for generated input object types
|
44
38
|
# @param new_class [Class] The base class to use for generating input object definitions
|
@@ -23,6 +23,8 @@ module GraphQL
|
|
23
23
|
# Really we only need description from here, but:
|
24
24
|
extend Schema::Member::BaseDSLMethods
|
25
25
|
extend GraphQL::Schema::Member::HasArguments
|
26
|
+
include Schema::Member::HasPath
|
27
|
+
extend Schema::Member::HasPath
|
26
28
|
|
27
29
|
# @param object [Object] the initialize object, pass to {Query.initialize} as `root_value`
|
28
30
|
# @param context [GraphQL::Query::Context]
|
@@ -72,7 +74,6 @@ module GraphQL
|
|
72
74
|
else
|
73
75
|
authorized?
|
74
76
|
end
|
75
|
-
authorized?(loaded_args)
|
76
77
|
context.schema.after_lazy(authorized_val) do |(authorized_result, early_return)|
|
77
78
|
# If the `authorized?` returned two values, `false, early_return`,
|
78
79
|
# then use the early return value instead of continuing
|
@@ -323,13 +324,32 @@ module GraphQL
|
|
323
324
|
# @see {GraphQL::Schema::Argument#initialize} for the signature
|
324
325
|
def argument(name, type, *rest, loads: nil, **kwargs, &block)
|
325
326
|
if loads
|
326
|
-
|
327
|
-
|
328
|
-
|
327
|
+
name_as_string = name.to_s
|
328
|
+
|
329
|
+
inferred_arg_name = case name_as_string
|
330
|
+
when /_id$/
|
331
|
+
name_as_string.sub(/_id$/, "").to_sym
|
332
|
+
when /_ids$/
|
333
|
+
name_as_string.sub(/_ids$/, "")
|
334
|
+
.sub(/([^s])$/, "\\1s")
|
335
|
+
.to_sym
|
336
|
+
else
|
337
|
+
name
|
338
|
+
end
|
339
|
+
|
340
|
+
kwargs[:as] ||= inferred_arg_name
|
341
|
+
own_arguments_loads_as_type[kwargs[:as]] = loads
|
329
342
|
end
|
343
|
+
|
330
344
|
arg_defn = super(name, type, *rest, **kwargs, &block)
|
331
345
|
|
332
|
-
if loads
|
346
|
+
if loads && arg_defn.type.list?
|
347
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
348
|
+
def load_#{arg_defn.keyword}(values)
|
349
|
+
GraphQL::Execution::Lazy.all(values.map { |value| load_application_object(:#{arg_defn.keyword}, value) })
|
350
|
+
end
|
351
|
+
RUBY
|
352
|
+
elsif loads
|
333
353
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
334
354
|
def load_#{arg_defn.keyword}(value)
|
335
355
|
load_application_object(:#{arg_defn.keyword}, value)
|
@@ -39,7 +39,7 @@ module GraphQL
|
|
39
39
|
# })
|
40
40
|
#
|
41
41
|
# payload = {
|
42
|
-
# result: result.subscription? ? nil : result.to_h,
|
42
|
+
# result: result.subscription? ? { data: nil } : result.to_h,
|
43
43
|
# more: result.subscription?,
|
44
44
|
# }
|
45
45
|
#
|
@@ -54,9 +54,28 @@ module GraphQL
|
|
54
54
|
#
|
55
55
|
# def unsubscribed
|
56
56
|
# @subscription_ids.each { |sid|
|
57
|
-
#
|
57
|
+
# MySchema.subscriptions.delete_subscription(sid)
|
58
58
|
# }
|
59
59
|
# end
|
60
|
+
#
|
61
|
+
# private
|
62
|
+
#
|
63
|
+
# def ensure_hash(ambiguous_param)
|
64
|
+
# case ambiguous_param
|
65
|
+
# when String
|
66
|
+
# if ambiguous_param.present?
|
67
|
+
# ensure_hash(JSON.parse(ambiguous_param))
|
68
|
+
# else
|
69
|
+
# {}
|
70
|
+
# end
|
71
|
+
# when Hash, ActionController::Parameters
|
72
|
+
# ambiguous_param
|
73
|
+
# when nil
|
74
|
+
# {}
|
75
|
+
# else
|
76
|
+
# raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
|
77
|
+
# end
|
78
|
+
# end
|
60
79
|
# end
|
61
80
|
#
|
62
81
|
class ActionCableSubscriptions < GraphQL::Subscriptions
|
@@ -19,6 +19,7 @@ module GraphQL
|
|
19
19
|
# Recursively transform a `.define`-DSL-based type expression into a class-ready expression, for example:
|
20
20
|
#
|
21
21
|
# - `types[X]` -> `[X, null: true]`
|
22
|
+
# - `types[X.to_non_null_type]` -> `[X]`
|
22
23
|
# - `Int` -> `Integer`
|
23
24
|
# - `X!` -> `X`
|
24
25
|
#
|
@@ -37,6 +38,9 @@ module GraphQL
|
|
37
38
|
if inner_type.start_with?("!")
|
38
39
|
nullable = false
|
39
40
|
inner_type = inner_type[1..-1]
|
41
|
+
elsif inner_type.end_with?(".to_non_null_type")
|
42
|
+
nullable = false
|
43
|
+
inner_type = inner_type[0...-17]
|
40
44
|
else
|
41
45
|
nullable = true
|
42
46
|
end
|
@@ -647,6 +651,7 @@ module GraphQL
|
|
647
651
|
|
648
652
|
if return_type
|
649
653
|
non_nullable = return_type.sub! /(^|[^\[])!/, '\1'
|
654
|
+
non_nullable ||= return_type.sub! /([^\[])\.to_non_null_type([^\]]|$)/, '\1'
|
650
655
|
nullable = !non_nullable
|
651
656
|
return_type = normalize_type_expression(return_type)
|
652
657
|
else
|
data/lib/graphql/version.rb
CHANGED
data/spec/dummy/Gemfile
CHANGED
@@ -130,6 +130,11 @@ describe GraphQL::EnumType do
|
|
130
130
|
assert_equal({ "COW" => cow, "GOAT" => goat }, enum.values)
|
131
131
|
end
|
132
132
|
|
133
|
+
it "values respond to graphql_name" do
|
134
|
+
cow = GraphQL::EnumType::EnumValue.define(name: "COW")
|
135
|
+
assert_equal("COW", cow.graphql_name)
|
136
|
+
end
|
137
|
+
|
133
138
|
describe "#dup" do
|
134
139
|
it "copies the values map without altering the original" do
|
135
140
|
enum_2 = enum.dup
|
@@ -160,6 +160,19 @@ describe GraphQL::Execution::Multiplex do
|
|
160
160
|
raise GraphQL::Error, "Crash"
|
161
161
|
}
|
162
162
|
end
|
163
|
+
|
164
|
+
field :raiseSyntaxError, types.String do
|
165
|
+
resolve ->(object, args, ctx) {
|
166
|
+
raise SyntaxError
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
field :raiseException, types.String do
|
171
|
+
resolve ->(object, args, ctx) {
|
172
|
+
raise Exception
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
163
176
|
end
|
164
177
|
|
165
178
|
InspectSchema = GraphQL::Schema.define do
|
@@ -167,6 +180,8 @@ describe GraphQL::Execution::Multiplex do
|
|
167
180
|
instrument(:query, InspectQueryInstrumentation)
|
168
181
|
end
|
169
182
|
|
183
|
+
unhandled_err_json = '{}'
|
184
|
+
|
170
185
|
it "can access the query results" do
|
171
186
|
InspectSchema.execute("{ raiseExecutionError }")
|
172
187
|
handled_err_json = '{"data":{"raiseExecutionError":null},"errors":[{"message":"Whoops","locations":[{"line":1,"column":3}],"path":["raiseExecutionError"]}]}'
|
@@ -176,7 +191,19 @@ describe GraphQL::Execution::Multiplex do
|
|
176
191
|
assert_raises(GraphQL::Error) do
|
177
192
|
InspectSchema.execute("{ raiseError }")
|
178
193
|
end
|
179
|
-
|
194
|
+
|
195
|
+
assert_equal unhandled_err_json, InspectQueryInstrumentation.last_json
|
196
|
+
end
|
197
|
+
|
198
|
+
it "can access the query results when the error is not a StandardError" do
|
199
|
+
assert_raises(SyntaxError) do
|
200
|
+
InspectSchema.execute("{ raiseSyntaxError }")
|
201
|
+
end
|
202
|
+
assert_equal unhandled_err_json, InspectQueryInstrumentation.last_json
|
203
|
+
|
204
|
+
assert_raises(Exception) do
|
205
|
+
InspectSchema.execute("{ raiseException }")
|
206
|
+
end
|
180
207
|
assert_equal unhandled_err_json, InspectQueryInstrumentation.last_json
|
181
208
|
end
|
182
209
|
end
|
@@ -124,7 +124,9 @@ describe GraphQL::InternalRepresentation::Rewrite do
|
|
124
124
|
|
125
125
|
nut_selections = plant_selection.typed_children[schema.types["Nut"]]
|
126
126
|
# `... on Tree`, `... on Nut`, and `NutFields`, but not `... on Fruit { ... on Tree }`
|
127
|
+
|
127
128
|
assert_equal 3, nut_selections["leafType"].ast_nodes.size
|
129
|
+
|
128
130
|
# Multi-level merging when including fragments:
|
129
131
|
habitats_selections = nut_selections["habitats"].typed_children[schema.types["Habitat"]]
|
130
132
|
assert_equal ["averageWeight", "seasons"], habitats_selections.keys
|
@@ -29,7 +29,11 @@ describe GraphQL::Schema::Argument do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
describe "#path" do
|
33
|
+
it "includes type, field and argument names" do
|
34
|
+
assert_equal "Query.field.argWithBlock", SchemaArgumentTest::Query.fields["field"].arguments["argWithBlock"].path
|
35
|
+
end
|
36
|
+
end
|
33
37
|
|
34
38
|
describe "#name" do
|
35
39
|
it "reflects camelization" do
|
@@ -3,6 +3,13 @@ require "spec_helper"
|
|
3
3
|
|
4
4
|
describe GraphQL::Schema::Enum do
|
5
5
|
let(:enum) { Jazz::Family }
|
6
|
+
|
7
|
+
describe ".path" do
|
8
|
+
it "is the name" do
|
9
|
+
assert_equal "Family", enum.path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
6
13
|
describe "type info" do
|
7
14
|
it "tells about the definition" do
|
8
15
|
assert_equal "Family", enum.graphql_name
|
@@ -2,6 +2,17 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
4
|
describe GraphQL::Schema::EnumValue do
|
5
|
+
describe "#path" do
|
6
|
+
it "Has the owner name too" do
|
7
|
+
enum = Class.new(GraphQL::Schema::Enum) do
|
8
|
+
graphql_name "Abc"
|
9
|
+
value(:XYZ)
|
10
|
+
end
|
11
|
+
|
12
|
+
assert_equal "Abc.XYZ", enum.values["XYZ"].path
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
5
16
|
describe "#deprecation_reason" do
|
6
17
|
it "can be written and read" do
|
7
18
|
enum_value = GraphQL::Schema::EnumValue.new(:x, owner: nil)
|
@@ -6,6 +6,13 @@ describe GraphQL::Schema::Field do
|
|
6
6
|
let(:object_class) { Jazz::Query }
|
7
7
|
let(:field) { object_class.fields["inspectInput"] }
|
8
8
|
|
9
|
+
describe "path" do
|
10
|
+
it "is the object/interface and field name" do
|
11
|
+
assert_equal "Query.inspectInput", field.path
|
12
|
+
assert_equal "GloballyIdentifiable.id", Jazz::GloballyIdentifiableType.fields["id"].path
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
9
16
|
it "uses the argument class" do
|
10
17
|
arg_defn = field.graphql_definition.arguments.values.first
|
11
18
|
assert_equal :ok, arg_defn.metadata[:custom]
|
@@ -3,6 +3,17 @@ require "spec_helper"
|
|
3
3
|
|
4
4
|
describe GraphQL::Schema::InputObject do
|
5
5
|
let(:input_object) { Jazz::EnsembleInput }
|
6
|
+
|
7
|
+
describe ".path" do
|
8
|
+
it "is the name" do
|
9
|
+
assert_equal "EnsembleInput", input_object.path
|
10
|
+
end
|
11
|
+
|
12
|
+
it "is used in argument paths" do
|
13
|
+
assert_equal "EnsembleInput.name", input_object.arguments["name"].path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
6
17
|
describe "type info" do
|
7
18
|
it "has it" do
|
8
19
|
assert_equal "EnsembleInput", input_object.graphql_name
|
@@ -4,6 +4,12 @@ require "spec_helper"
|
|
4
4
|
describe GraphQL::Schema::Interface do
|
5
5
|
let(:interface) { Jazz::GloballyIdentifiableType }
|
6
6
|
|
7
|
+
describe ".path" do
|
8
|
+
it "is the name" do
|
9
|
+
assert_equal "GloballyIdentifiable", interface.path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
describe "type info" do
|
8
14
|
it "tells its type info" do
|
9
15
|
assert_equal "GloballyIdentifiable", interface.graphql_name
|