Skip to content

Commit 177f9e5

Browse files
committed
Add support for GraphQL 2.0
field_class must be specified in MutationType in order to allow defining `authenticate` for each mutation field. If not defined default `authenticate` value will be used
1 parent f648b6a commit 177f9e5

23 files changed

Lines changed: 139 additions & 18 deletions

.circleci/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ workflows:
6868
- gemfiles/rails6.1_graphql1.11.gemfile
6969
- gemfiles/rails6.1_graphql1.12.gemfile
7070
- gemfiles/rails6.1_graphql1.13.gemfile
71+
- gemfiles/rails6.1_graphql2.0.gemfile
7172
- gemfiles/rails7.0_graphql1.11.gemfile
7273
- gemfiles/rails7.0_graphql1.12.gemfile
7374
- gemfiles/rails7.0_graphql1.13.gemfile
@@ -84,6 +85,8 @@ workflows:
8485
gemfile: gemfiles/rails6.1_graphql1.12.gemfile
8586
- ruby-version: '2.2'
8687
gemfile: gemfiles/rails6.1_graphql1.13.gemfile
88+
- ruby-version: '2.2'
89+
gemfile: gemfiles/rails6.1_graphql2.0.gemfile
8790
- ruby-version: '2.3'
8891
gemfile: gemfiles/rails6.0_graphql1.11.gemfile
8992
- ruby-version: '2.3'
@@ -96,6 +99,8 @@ workflows:
9699
gemfile: gemfiles/rails6.1_graphql1.12.gemfile
97100
- ruby-version: '2.3'
98101
gemfile: gemfiles/rails6.1_graphql1.13.gemfile
102+
- ruby-version: '2.3'
103+
gemfile: gemfiles/rails6.1_graphql2.0.gemfile
99104
- ruby-version: '2.4'
100105
gemfile: gemfiles/rails6.0_graphql1.11.gemfile
101106
- ruby-version: '2.4'
@@ -108,6 +113,8 @@ workflows:
108113
gemfile: gemfiles/rails6.1_graphql1.12.gemfile
109114
- ruby-version: '2.4'
110115
gemfile: gemfiles/rails6.1_graphql1.13.gemfile
116+
- ruby-version: '2.4'
117+
gemfile: gemfiles/rails6.1_graphql2.0.gemfile
111118
- ruby-version: '2.4'
112119
gemfile: gemfiles/rails7.0_graphql1.11.gemfile
113120
- ruby-version: '2.4'
@@ -122,6 +129,8 @@ workflows:
122129
gemfile: gemfiles/rails6.1_graphql1.13.gemfile
123130
- ruby-version: '2.5'
124131
gemfile: gemfiles/rails7.0_graphql1.12.gemfile
132+
- ruby-version: '2.5'
133+
gemfile: gemfiles/rails6.1_graphql2.0.gemfile
125134
- ruby-version: '2.5'
126135
gemfile: gemfiles/rails7.0_graphql1.13.gemfile
127136
- ruby-version: '2.6'

Appraisals

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ appraise 'rails6.1-graphql1.13' do
138138
gem 'graphql', '~> 1.13.0'
139139
end
140140

141+
appraise 'rails6.1-graphql2.0' do
142+
gem 'sqlite3', '~> 1.4'
143+
gem 'devise', '>= 4.7'
144+
gem 'rails', git: 'https://github.com/rails/rails', branch: '6-1-stable'
145+
gem 'graphql', '~> 2.0.1'
146+
end
147+
141148
appraise 'rails7.0-graphql1.10' do
142149
gem 'sassc-rails'
143150
gem 'sqlite3', '~> 1.4'

gemfiles/.bundle/config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
---
22
BUNDLE_RETRY: "1"
3+
BUNDLE_WITHOUT: "production"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file was generated by Appraisal
2+
3+
source "https://rubygems.org"
4+
5+
gem "sqlite3", "~> 1.4"
6+
gem "devise", ">= 4.7"
7+
gem "rails", git: "https://github.com/rails/rails", branch: "6-1-stable"
8+
gem "graphql", "~> 2.0.1"
9+
10+
gemspec path: "../"

graphql_devise.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
2828
spec.required_ruby_version = '>= 2.4.4'
2929

3030
spec.add_dependency 'devise_token_auth', '>= 0.1.43', '< 2.0'
31-
spec.add_dependency 'graphql', '>= 1.8', '< 1.14.0'
31+
spec.add_dependency 'graphql', '>= 1.8', '< 2.1'
3232
spec.add_dependency 'rails', '>= 4.2', '< 7.1'
3333
spec.add_dependency 'zeitwerk'
3434

lib/graphql_devise.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
require 'devise_token_auth'
77
require 'zeitwerk'
88

9-
GraphQL::Field.accepts_definitions(authenticate: GraphQL::Define.assign_metadata_key(:authenticate))
10-
GraphQL::Schema::Field.accepts_definition(:authenticate)
9+
if Gem::Version.new(GraphQL::VERSION) < Gem::Version.new('2.0')
10+
GraphQL::Field.accepts_definitions(authenticate: GraphQL::Define.assign_metadata_key(:authenticate))
11+
GraphQL::Schema::Field.accepts_definition(:authenticate)
12+
end
1113

1214
loader = Zeitwerk::Loader.for_gem
1315

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# frozen_string_literal: true
2+
3+
module GraphqlDevise
4+
module FieldAuthentication
5+
extend ActiveSupport::Concern
6+
7+
def initialize(*args, authenticate: nil, **kwargs, &block)
8+
@authenticate = authenticate
9+
super(*args, **kwargs, &block)
10+
end
11+
12+
attr_reader :authenticate
13+
end
14+
end

lib/graphql_devise/resource_loader.rb

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ def call(query, mutation)
3535
raise ::GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped'
3636
end
3737

38-
prepared_mutations.each do |action, prepared_mutation|
39-
mutation.field(action, mutation: prepared_mutation, authenticate: false)
38+
begin
39+
prepared_mutations.each do |action, prepared_mutation|
40+
mutation.field(action, mutation: prepared_mutation, authenticate: false)
41+
end
42+
rescue ArgumentError
43+
raise unless Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
44+
45+
raise_undefined_field_class_error('MutationType')
4046
end
4147

4248
prepared_resolvers = prepare_resolvers(@resource, clean_options, authenticatable_type)
@@ -45,8 +51,14 @@ def call(query, mutation)
4551
raise ::GraphqlDevise::Error, 'You need to provide a query type unless all queries are skipped'
4652
end
4753

48-
prepared_resolvers.each do |action, resolver|
49-
query.field(action, resolver: resolver, authenticate: false)
54+
begin
55+
prepared_resolvers.each do |action, resolver|
56+
query.field(action, resolver: resolver, authenticate: false)
57+
end
58+
rescue ArgumentError
59+
raise unless Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
60+
61+
raise_undefined_field_class_error('QueryType')
5062
end
5163

5264
::GraphqlDevise.add_mapping(::GraphqlDevise.to_mapping_name(@resource).to_sym, @resource)
@@ -57,6 +69,35 @@ def call(query, mutation)
5769

5870
private
5971

72+
def raise_undefined_field_class_error(type_class)
73+
raise(
74+
GraphqlDevise::Error,
75+
<<~MESSAGE
76+
To use this gem with graphql >= 2.0 you need to use a custom `field_class`
77+
on your #{type_class}. You can use the `field_class` defined in this gem like this:
78+
79+
module Types
80+
class #{type_class} < GraphQL::Schema::Object
81+
field_class GraphqlDevise::Types::BaseField
82+
end
83+
end
84+
85+
If you already have a `field_class` set on your #{type_class}, you can include our concern
86+
to make this work
87+
88+
module Types
89+
class BaseField < GraphQL::Schema::Field
90+
include GraphqlDevise::FieldAuthentication
91+
end
92+
end
93+
94+
The concern will define an initializer, if your custom field logic is not standard, you can look
95+
at the `GraphqlDevise::FieldAuthentication` implementation to add what is required to your own
96+
field class
97+
MESSAGE
98+
)
99+
end
100+
60101
def prepare_resolvers(model, clean_options, authenticatable_type)
61102
MountMethod::OperationPreparer.new(
62103
model: model,

lib/graphql_devise/schema_plugin.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ def authenticate_option(field, trace_data)
7979
auth_required = if trace_data[:context]
8080
field.metadata[:authenticate]
8181
else
82-
if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.13.1')
82+
if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('2.0')
83+
# authenticate will only be defined if "field_class GraphqlDevise::Types::BaseField" is added to the type
84+
# returning nil here will use the default value used when mounting the plugin
85+
field.try(:authenticate)
86+
elsif Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.13.1')
8387
field.graphql_definition(silence_deprecation_warning: true).metadata[:authenticate]
8488
else
8589
field.graphql_definition.metadata[:authenticate]

lib/graphql_devise/types/authenticatable_type.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module GraphqlDevise
44
module Types
5-
class AuthenticatableType < GraphQL::Schema::Object
5+
class AuthenticatableType < BaseType
66
field :email, String, null: false
77
end
88
end

0 commit comments

Comments
 (0)