graphql_rails 0.1.0 → 0.2.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/.gitignore +1 -0
- data/Gemfile.lock +2 -2
- data/README.md +76 -8
- data/graphql_rails.gemspec +1 -1
- data/lib/graphql_rails/attribute.rb +7 -42
- data/lib/graphql_rails/attribute/attribute_type_parser.rb +99 -0
- data/lib/graphql_rails/controller.rb +17 -5
- data/lib/graphql_rails/controller/action.rb +93 -0
- data/lib/graphql_rails/controller/action_configuration.rb +1 -2
- data/lib/graphql_rails/controller/controller_function.rb +7 -6
- data/lib/graphql_rails/controller/request.rb +3 -3
- data/lib/graphql_rails/model.rb +1 -1
- data/lib/graphql_rails/model/configuration.rb +14 -50
- data/lib/graphql_rails/model/graphql_type_builder.rb +37 -0
- data/lib/graphql_rails/router.rb +36 -19
- data/lib/graphql_rails/router/{mutation_action.rb → mutation_route.rb} +2 -2
- data/lib/graphql_rails/router/{query_action.rb → query_route.rb} +2 -2
- data/lib/graphql_rails/router/resource_routes_builder.rb +82 -0
- data/lib/graphql_rails/router/route.rb +40 -0
- data/lib/graphql_rails/router/schema_builder.rb +9 -5
- data/lib/graphql_rails/rspec_controller_helpers.rb +94 -0
- data/lib/graphql_rails/version.rb +1 -1
- metadata +14 -29
- data/lib/graphiti.rb +0 -10
- data/lib/graphiti/attribute.rb +0 -86
- data/lib/graphiti/controller.rb +0 -54
- data/lib/graphiti/controller/action_configuration.rb +0 -46
- data/lib/graphiti/controller/configuration.rb +0 -32
- data/lib/graphiti/controller/controller_function.rb +0 -41
- data/lib/graphiti/controller/request.rb +0 -40
- data/lib/graphiti/errors/execution_error.rb +0 -18
- data/lib/graphiti/errors/validation_error.rb +0 -26
- data/lib/graphiti/model.rb +0 -33
- data/lib/graphiti/model/configuration.rb +0 -81
- data/lib/graphiti/router.rb +0 -65
- data/lib/graphiti/router/action.rb +0 -21
- data/lib/graphiti/router/mutation_action.rb +0 -18
- data/lib/graphiti/router/query_action.rb +0 -18
- data/lib/graphiti/router/resource_actions_builder.rb +0 -82
- data/lib/graphiti/router/schema_builder.rb +0 -37
- data/lib/graphiti/version.rb +0 -5
- data/lib/graphql_rails/controller/action_path_parser.rb +0 -75
- data/lib/graphql_rails/router/action.rb +0 -21
- data/lib/graphql_rails/router/resource_actions_builder.rb +0 -82
@@ -4,18 +4,22 @@ module GraphqlRails
|
|
4
4
|
class Router
|
5
5
|
# builds GraphQL::Schema based on previously defined grahiti data
|
6
6
|
class SchemaBuilder
|
7
|
-
attr_reader :queries, :mutations
|
7
|
+
attr_reader :queries, :mutations, :raw_actions
|
8
8
|
|
9
|
-
def initialize(queries:, mutations:)
|
9
|
+
def initialize(queries:, mutations:, raw_actions:)
|
10
10
|
@queries = queries
|
11
11
|
@mutations = mutations
|
12
|
+
@raw_actions = raw_actions
|
12
13
|
end
|
13
14
|
|
14
15
|
def call
|
15
16
|
query_type = build_type('Query', queries)
|
16
17
|
mutation_type = build_type('Mutation', mutations)
|
18
|
+
raw = raw_actions
|
17
19
|
|
18
20
|
GraphQL::Schema.define do
|
21
|
+
raw.each { |action| send(action[:name], *action[:args], &action[:block]) }
|
22
|
+
|
19
23
|
query(query_type)
|
20
24
|
mutation(mutation_type)
|
21
25
|
end
|
@@ -23,12 +27,12 @@ module GraphqlRails
|
|
23
27
|
|
24
28
|
private
|
25
29
|
|
26
|
-
def build_type(type_name,
|
30
|
+
def build_type(type_name, routes)
|
27
31
|
GraphQL::ObjectType.define do
|
28
32
|
name type_name
|
29
33
|
|
30
|
-
|
31
|
-
field
|
34
|
+
routes.each do |route|
|
35
|
+
field route.name, Controller::ControllerFunction.from_route(route)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql_rails'
|
4
|
+
|
5
|
+
module GraphqlRails
|
6
|
+
# provides all helpers neccesary for testing graphql controllers. It is similar to rspec controller specs
|
7
|
+
#
|
8
|
+
# Adds 3 helper methods in to rspec test:
|
9
|
+
# * mutation
|
10
|
+
# * query
|
11
|
+
# * result
|
12
|
+
# `mutation` and `query`` methods are identical
|
13
|
+
#
|
14
|
+
# Usage:
|
15
|
+
# it 'works' do
|
16
|
+
# mutation(:createUser, params: { name: 'John'}, context: { current_user_id: 1 })
|
17
|
+
# expect(response).to be_successful?
|
18
|
+
# expect(response)not_to be_failure?
|
19
|
+
# expect(response.result).to be_a(User)
|
20
|
+
# expect(response.errors).to be_empty
|
21
|
+
# end
|
22
|
+
module RSpecControllerHelpers
|
23
|
+
# contains all details about testing response. Similar as in rspec controllers tests
|
24
|
+
class Response
|
25
|
+
def initialize(request)
|
26
|
+
@request = request
|
27
|
+
end
|
28
|
+
|
29
|
+
def result
|
30
|
+
request.object_to_return
|
31
|
+
end
|
32
|
+
|
33
|
+
def errors
|
34
|
+
request.errors
|
35
|
+
end
|
36
|
+
|
37
|
+
def success?
|
38
|
+
request.errors.empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
def successful?
|
42
|
+
success?
|
43
|
+
end
|
44
|
+
|
45
|
+
def failure?
|
46
|
+
!success?
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :request
|
52
|
+
end
|
53
|
+
|
54
|
+
# instance which has similar behavior as
|
55
|
+
class FakeContext
|
56
|
+
extend Forwardable
|
57
|
+
|
58
|
+
def_delegators :@provided_values, :[], :[]=, :to_h, :key?, :fetch
|
59
|
+
|
60
|
+
def initialize(values:)
|
61
|
+
@errors = []
|
62
|
+
@provided_values = values
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_error(error)
|
66
|
+
@errors << error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# controller request object more suitable for testing
|
71
|
+
class Request < GraphqlRails::Controller::Request
|
72
|
+
def initialize(params, context)
|
73
|
+
super(nil, params, context)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def query(query_name, params: {}, context: {})
|
78
|
+
context_object = FakeContext.new(values: context)
|
79
|
+
request = Request.new(params, context_object)
|
80
|
+
described_class.new(request).call(query_name)
|
81
|
+
|
82
|
+
@response = Response.new(request)
|
83
|
+
@response
|
84
|
+
end
|
85
|
+
|
86
|
+
def mutation(*args)
|
87
|
+
query(*args)
|
88
|
+
end
|
89
|
+
|
90
|
+
def response
|
91
|
+
@response
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Povilas Jurčys
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '4'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '4'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,29 +102,12 @@ files:
|
|
102
102
|
- bin/console
|
103
103
|
- bin/setup
|
104
104
|
- graphql_rails.gemspec
|
105
|
-
- lib/graphiti.rb
|
106
|
-
- lib/graphiti/attribute.rb
|
107
|
-
- lib/graphiti/controller.rb
|
108
|
-
- lib/graphiti/controller/action_configuration.rb
|
109
|
-
- lib/graphiti/controller/configuration.rb
|
110
|
-
- lib/graphiti/controller/controller_function.rb
|
111
|
-
- lib/graphiti/controller/request.rb
|
112
|
-
- lib/graphiti/errors/execution_error.rb
|
113
|
-
- lib/graphiti/errors/validation_error.rb
|
114
|
-
- lib/graphiti/model.rb
|
115
|
-
- lib/graphiti/model/configuration.rb
|
116
|
-
- lib/graphiti/router.rb
|
117
|
-
- lib/graphiti/router/action.rb
|
118
|
-
- lib/graphiti/router/mutation_action.rb
|
119
|
-
- lib/graphiti/router/query_action.rb
|
120
|
-
- lib/graphiti/router/resource_actions_builder.rb
|
121
|
-
- lib/graphiti/router/schema_builder.rb
|
122
|
-
- lib/graphiti/version.rb
|
123
105
|
- lib/graphql_rails.rb
|
124
106
|
- lib/graphql_rails/attribute.rb
|
107
|
+
- lib/graphql_rails/attribute/attribute_type_parser.rb
|
125
108
|
- lib/graphql_rails/controller.rb
|
109
|
+
- lib/graphql_rails/controller/action.rb
|
126
110
|
- lib/graphql_rails/controller/action_configuration.rb
|
127
|
-
- lib/graphql_rails/controller/action_path_parser.rb
|
128
111
|
- lib/graphql_rails/controller/configuration.rb
|
129
112
|
- lib/graphql_rails/controller/controller_function.rb
|
130
113
|
- lib/graphql_rails/controller/request.rb
|
@@ -132,12 +115,14 @@ files:
|
|
132
115
|
- lib/graphql_rails/errors/validation_error.rb
|
133
116
|
- lib/graphql_rails/model.rb
|
134
117
|
- lib/graphql_rails/model/configuration.rb
|
118
|
+
- lib/graphql_rails/model/graphql_type_builder.rb
|
135
119
|
- lib/graphql_rails/router.rb
|
136
|
-
- lib/graphql_rails/router/
|
137
|
-
- lib/graphql_rails/router/
|
138
|
-
- lib/graphql_rails/router/
|
139
|
-
- lib/graphql_rails/router/
|
120
|
+
- lib/graphql_rails/router/mutation_route.rb
|
121
|
+
- lib/graphql_rails/router/query_route.rb
|
122
|
+
- lib/graphql_rails/router/resource_routes_builder.rb
|
123
|
+
- lib/graphql_rails/router/route.rb
|
140
124
|
- lib/graphql_rails/router/schema_builder.rb
|
125
|
+
- lib/graphql_rails/rspec_controller_helpers.rb
|
141
126
|
- lib/graphql_rails/version.rb
|
142
127
|
homepage: https://github.com/povilasjurcys/graphql_rails
|
143
128
|
licenses:
|
data/lib/graphiti.rb
DELETED
data/lib/graphiti/attribute.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'graphql'
|
4
|
-
|
5
|
-
module GraphqlRails
|
6
|
-
# contains info about single graphql attribute
|
7
|
-
class Attribute
|
8
|
-
attr_reader :name, :type
|
9
|
-
|
10
|
-
def initialize(name, type = nil, required: false, hidden: false)
|
11
|
-
@name = name.to_s
|
12
|
-
@type = parse_type(type || type_by_attribute_name)
|
13
|
-
@required = required
|
14
|
-
@hidden = hidden
|
15
|
-
end
|
16
|
-
|
17
|
-
def graphql_field_type
|
18
|
-
@graphql_field_type ||= required? ? type.to_non_null_type : type
|
19
|
-
end
|
20
|
-
|
21
|
-
def required?
|
22
|
-
@required
|
23
|
-
end
|
24
|
-
|
25
|
-
def hidden?
|
26
|
-
@hidden
|
27
|
-
end
|
28
|
-
|
29
|
-
def field_name
|
30
|
-
field =
|
31
|
-
if name.end_with?('?')
|
32
|
-
"is_#{name.remove(/\?\Z/)}"
|
33
|
-
else
|
34
|
-
name
|
35
|
-
end
|
36
|
-
|
37
|
-
field.camelize(:lower)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def type_by_attribute_name
|
43
|
-
case name
|
44
|
-
when 'id', /_id\Z/
|
45
|
-
GraphQL::ID_TYPE
|
46
|
-
when /\?\Z/
|
47
|
-
GraphQL::BOOLEAN_TYPE
|
48
|
-
else
|
49
|
-
GraphQL::STRING_TYPE
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def parse_type(type)
|
54
|
-
if graphql_type?(type)
|
55
|
-
type
|
56
|
-
elsif type.is_a?(String) || type.is_a?(Symbol)
|
57
|
-
map_type_name_to_type(type.to_s.downcase)
|
58
|
-
else
|
59
|
-
raise "Unsupported type #{type.inspect} (class: #{type.class})"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def graphql_type?(type)
|
64
|
-
type.is_a?(GraphQL::BaseType) ||
|
65
|
-
type.is_a?(GraphQL::ObjectType) ||
|
66
|
-
(defined?(GraphQL::Schema::Member) && type.is_a?(Class) && type < GraphQL::Schema::Member)
|
67
|
-
end
|
68
|
-
|
69
|
-
def map_type_name_to_type(type_name)
|
70
|
-
case type_name
|
71
|
-
when 'id'
|
72
|
-
GraphQL::ID_TYPE
|
73
|
-
when 'int', 'integer'
|
74
|
-
GraphQL::INT_TYPE
|
75
|
-
when 'string', 'str', 'text', 'time', 'date'
|
76
|
-
GraphQL::STRING_TYPE
|
77
|
-
when 'bool', 'boolean', 'mongoid::boolean'
|
78
|
-
GraphQL::BOOLEAN_TYPE
|
79
|
-
when 'float', 'double', 'decimal'
|
80
|
-
GraphQL::FLOAT_TYPE
|
81
|
-
else
|
82
|
-
raise "Don't know how to parse type with name #{type_name.inspect}"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/graphiti/controller.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/hash_with_indifferent_access'
|
4
|
-
require_relative 'controller/configuration'
|
5
|
-
require_relative 'controller/request'
|
6
|
-
|
7
|
-
module GraphqlRails
|
8
|
-
# base class for all graphql_rails controllers
|
9
|
-
class Controller
|
10
|
-
class << self
|
11
|
-
def before_action(action_name)
|
12
|
-
controller_configuration.add_before_action(action_name)
|
13
|
-
end
|
14
|
-
|
15
|
-
def action(method_name)
|
16
|
-
controller_configuration.action(method_name)
|
17
|
-
end
|
18
|
-
|
19
|
-
def controller_configuration
|
20
|
-
@controller_configuration ||= Controller::Configuration.new(self)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(graphql_request)
|
25
|
-
@graphql_request = graphql_request
|
26
|
-
end
|
27
|
-
|
28
|
-
def call(method_name)
|
29
|
-
self.class.controller_configuration.before_actions.each { |action_name| send(action_name) }
|
30
|
-
|
31
|
-
begin
|
32
|
-
response = public_send(method_name)
|
33
|
-
render response if graphql_request.no_object_to_return?
|
34
|
-
rescue StandardError => error
|
35
|
-
render error: error
|
36
|
-
end
|
37
|
-
|
38
|
-
graphql_request.object_to_return
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
attr_reader :graphql_request
|
44
|
-
|
45
|
-
def render(object = nil, error: nil, errors: Array(error))
|
46
|
-
graphql_request.errors = errors
|
47
|
-
graphql_request.object_to_return = object
|
48
|
-
end
|
49
|
-
|
50
|
-
def params
|
51
|
-
@params = HashWithIndifferentAccess.new(graphql_request.params)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string/filters'
|
4
|
-
require 'graphql_rails/attribute'
|
5
|
-
|
6
|
-
module GraphqlRails
|
7
|
-
class Controller
|
8
|
-
# stores all graphql_rails contoller specific config
|
9
|
-
class ActionConfiguration
|
10
|
-
attr_reader :attributes, :return_type
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@attributes = {}
|
14
|
-
@can_return_nil = false
|
15
|
-
end
|
16
|
-
|
17
|
-
def permit(*no_type_attributes, **typed_attributes)
|
18
|
-
no_type_attributes.each { |attribute| permit_attribute(attribute) }
|
19
|
-
typed_attributes.each { |attribute, type| permit_attribute(attribute, type) }
|
20
|
-
self
|
21
|
-
end
|
22
|
-
|
23
|
-
def can_return_nil
|
24
|
-
@can_return_nil = true
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
def returns(new_return_type)
|
29
|
-
@return_type = new_return_type
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
def can_return_nil?
|
34
|
-
@can_return_nil
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def permit_attribute(name, type = nil)
|
40
|
-
field_name = name.to_s.remove(/!\Z/)
|
41
|
-
required = name.to_s.end_with?('!')
|
42
|
-
attributes[field_name] = Attribute.new(field_name, type, required: required)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string/inflections'
|
4
|
-
require 'graphql_rails/attribute'
|
5
|
-
require 'graphql_rails/controller/action_configuration'
|
6
|
-
|
7
|
-
module GraphqlRails
|
8
|
-
class Controller
|
9
|
-
# stores all graphql_rails contoller specific config
|
10
|
-
class Configuration
|
11
|
-
attr_reader :before_actions
|
12
|
-
|
13
|
-
def initialize(controller)
|
14
|
-
@controller = controller
|
15
|
-
@before_actions = Set.new
|
16
|
-
@action_by_name = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
def add_before_action(name)
|
20
|
-
before_actions << name
|
21
|
-
end
|
22
|
-
|
23
|
-
def action(method_name)
|
24
|
-
@action_by_name[method_name.to_s] ||= ActionConfiguration.new
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
attr_reader :controller
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|