graphql_rails 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3c30cddc8d921388e200982dc22033da8a3decd449fa44a228d320a52bfd18a
4
- data.tar.gz: a783527f323172eac78cf725beea3b931b94f9ad2b8477e59d8cf395c8122c43
3
+ metadata.gz: f314505789425775da7e899dd4d30bbc6558da828af5b3f617a84d42eb8f4933
4
+ data.tar.gz: 9afab45a8f249aadf6540715514d2f7e21a713290fa7f753fc1933bc574cb18a
5
5
  SHA512:
6
- metadata.gz: f76e5e25f3c1e58c557b8dbeb77d0dba51815c9dd442c6adcd30e82481fb4b999831c2bf8b4beaae05c79e18226d04db6069b35e68bb845a201e171aa9000fb2
7
- data.tar.gz: 7ca367ea5bbaf9341f0326f77eef2c515b29f233d8fb3000586cf3f16ecba1cd96f4e93dbe5106750fcd4ca2a99b7e7ca58e3b4aabde7eeab56bd0c94d58be31
6
+ metadata.gz: 0c5709a879b830f8beeccfd391ec0f4f7de83cc3af0d4a37880f3051ab00d2d06fc88794087c5b0f8a18331c5d059caca389894cdc36c722e11d4393546fb289
7
+ data.tar.gz: 9df5208778bfbe2a47c8e652ec2b5442747e51a5e5c4a315fbada63c92248d96d37a85d4598ec8210b5c2e8cc34e8df2f7731faf988ceefb6c91c499da38a68b
data/.rubocop.yml CHANGED
@@ -13,6 +13,9 @@ Metrics/BlockLength:
13
13
  Metrics/ModuleLength:
14
14
  Exclude:
15
15
  - spec/**/*_spec.rb
16
+ Metrics/ClassLength:
17
+ Exclude:
18
+ - spec/**/*_spec.rb
16
19
 
17
20
  Lint/AmbiguousBlockAssociation:
18
21
  Exclude:
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ ## [Unreleased]
2
+
3
+ * Your contribution here.
4
+
5
+ ## 0.5.0 (2019-04-03)
6
+
7
+ * [#56](https://github.com/ashkan18/graphlient/pull/56) Added GraphQL input type generators [@povilasjurcys](https://github.com/povilasjurcys).
8
+ * Added CHANGELOG [@povilasjurcys](https://github.com/povilasjurcys).
9
+ * Fixed GraphQL word typos in documentation and code [@povilasjurcys](https://github.com/povilasjurcys).
data/Gemfile.lock CHANGED
@@ -1,82 +1,84 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql_rails (0.4.3)
4
+ graphql_rails (0.5.0)
5
5
  activesupport (>= 4)
6
6
  graphql (~> 1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (5.2.0)
12
- activesupport (= 5.2.0)
13
- activerecord (5.2.0)
14
- activemodel (= 5.2.0)
15
- activesupport (= 5.2.0)
11
+ activemodel (5.2.2.1)
12
+ activesupport (= 5.2.2.1)
13
+ activerecord (5.2.2.1)
14
+ activemodel (= 5.2.2.1)
15
+ activesupport (= 5.2.2.1)
16
16
  arel (>= 9.0)
17
- activesupport (5.2.0)
17
+ activesupport (5.2.2.1)
18
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
19
19
  i18n (>= 0.7, < 2)
20
20
  minitest (~> 5.1)
21
21
  tzinfo (~> 1.1)
22
22
  arel (9.0.0)
23
23
  ast (2.4.0)
24
- bson (4.3.0)
25
- byebug (10.0.2)
26
- codecov (0.1.10)
24
+ bson (4.4.2)
25
+ byebug (11.0.1)
26
+ codecov (0.1.14)
27
27
  json
28
28
  simplecov
29
29
  url
30
30
  coderay (1.1.2)
31
- concurrent-ruby (1.0.5)
31
+ concurrent-ruby (1.1.5)
32
32
  diff-lcs (1.3)
33
- docile (1.3.0)
33
+ docile (1.3.1)
34
34
  graphql (1.9.3)
35
- i18n (1.0.1)
35
+ i18n (1.6.0)
36
36
  concurrent-ruby (~> 1.0)
37
- json (2.1.0)
38
- method_source (0.9.0)
37
+ jaro_winkler (1.5.2)
38
+ json (2.2.0)
39
+ method_source (0.9.2)
39
40
  minitest (5.11.3)
40
- mongo (2.5.1)
41
- bson (>= 4.3.0, < 5.0.0)
42
- mongoid (7.0.0)
41
+ mongo (2.8.0)
42
+ bson (>= 4.4.2, < 5.0.0)
43
+ mongoid (7.0.2)
43
44
  activemodel (>= 5.1, < 6.0.0)
44
45
  mongo (>= 2.5.1, < 3.0.0)
45
- parallel (1.12.1)
46
- parser (2.5.1.0)
46
+ parallel (1.16.0)
47
+ parser (2.6.2.0)
47
48
  ast (~> 2.4.0)
48
- powerpack (0.1.1)
49
- pry (0.11.3)
49
+ pry (0.12.2)
50
50
  coderay (~> 1.1.0)
51
51
  method_source (~> 0.9.0)
52
- pry-byebug (3.6.0)
53
- byebug (~> 10.0)
52
+ pry-byebug (3.7.0)
53
+ byebug (~> 11.0)
54
54
  pry (~> 0.10)
55
+ psych (3.1.0)
55
56
  rainbow (3.0.0)
56
57
  rake (10.5.0)
57
- rspec (3.7.0)
58
- rspec-core (~> 3.7.0)
59
- rspec-expectations (~> 3.7.0)
60
- rspec-mocks (~> 3.7.0)
61
- rspec-core (3.7.1)
62
- rspec-support (~> 3.7.0)
63
- rspec-expectations (3.7.0)
58
+ rspec (3.8.0)
59
+ rspec-core (~> 3.8.0)
60
+ rspec-expectations (~> 3.8.0)
61
+ rspec-mocks (~> 3.8.0)
62
+ rspec-core (3.8.0)
63
+ rspec-support (~> 3.8.0)
64
+ rspec-expectations (3.8.2)
64
65
  diff-lcs (>= 1.2.0, < 2.0)
65
- rspec-support (~> 3.7.0)
66
- rspec-mocks (3.7.0)
66
+ rspec-support (~> 3.8.0)
67
+ rspec-mocks (3.8.0)
67
68
  diff-lcs (>= 1.2.0, < 2.0)
68
- rspec-support (~> 3.7.0)
69
- rspec-support (3.7.1)
70
- rubocop (0.55.0)
69
+ rspec-support (~> 3.8.0)
70
+ rspec-support (3.8.0)
71
+ rubocop (0.66.0)
72
+ jaro_winkler (~> 1.5.1)
71
73
  parallel (~> 1.10)
72
- parser (>= 2.5)
73
- powerpack (~> 0.1)
74
+ parser (>= 2.5, != 2.5.1.1)
75
+ psych (>= 3.1.0)
74
76
  rainbow (>= 2.2.2, < 4.0)
75
77
  ruby-progressbar (~> 1.7)
76
- unicode-display_width (~> 1.0, >= 1.0.1)
77
- rubocop-rspec (1.25.1)
78
- rubocop (>= 0.53.0)
79
- ruby-progressbar (1.9.0)
78
+ unicode-display_width (>= 1.4.0, < 1.6)
79
+ rubocop-rspec (1.32.0)
80
+ rubocop (>= 0.60.0)
81
+ ruby-progressbar (1.10.0)
80
82
  simplecov (0.16.1)
81
83
  docile (~> 1.1)
82
84
  json (>= 1.8, < 3)
@@ -85,7 +87,7 @@ GEM
85
87
  thread_safe (0.3.6)
86
88
  tzinfo (1.2.5)
87
89
  thread_safe (~> 0.1)
88
- unicode-display_width (1.3.0)
90
+ unicode-display_width (1.5.0)
89
91
  url (0.3.2)
90
92
 
91
93
  PLATFORMS
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![codecov](https://codecov.io/gh/samesystem/graphql_rails/branch/master/graph/badge.svg)](https://codecov.io/gh/samesystem/graphql_rails)
5
5
  [![Documentation](https://readthedocs.org/projects/ansicolortags/badge/?version=latest)](https://samesystem.github.io/graphql_rails)
6
6
 
7
- Rails style structure for GrapQL API.
7
+ Rails style structure for GraphQL API.
8
8
 
9
9
  ## Installation
10
10
 
@@ -104,7 +104,7 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
104
104
  end
105
105
  ```
106
106
 
107
- ## Testing your GrapqhlRails::Controller in RSpec
107
+ ## Testing your GraphqlRails::Controller in RSpec
108
108
 
109
109
  ### Setup
110
110
 
@@ -175,7 +175,6 @@ end
175
175
 
176
176
  Check https://samesystem.github.io/graphql_rails for more details
177
177
 
178
-
179
178
  ## Development
180
179
 
181
180
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/docs/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # GraphqlRails
2
2
 
3
-
4
- Rails style structure for GrapQL API.
3
+ Rails style structure for GraphQL API.
5
4
 
6
5
  ## Installation
7
6
 
@@ -101,7 +100,7 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
101
100
  end
102
101
  ```
103
102
 
104
- ## Testing your GrapqhlRails::Controller in RSpec
103
+ ## Testing your GraphqlRails::Controller in RSpec
105
104
 
106
105
  ### Setup
107
106
 
@@ -46,6 +46,26 @@ class UsersController < GraphqlRails::Controller
46
46
  end
47
47
  ```
48
48
 
49
+ If your model has defined input, then you can provide your model as input type, like this:
50
+
51
+ ```ruby
52
+ class User
53
+ graphql.input do
54
+ c.attribute :name
55
+ end
56
+ end
57
+
58
+ class UsersController < GraphqlRails::Controller
59
+ action(:create).permit(create_params: 'User')
60
+ # this is equivalent to:
61
+ # `action(:create).permit(create_params: User.graphql.input)`
62
+
63
+ def create
64
+ User.create(params[:create_params])
65
+ end
66
+ end
67
+ ```
68
+
49
69
  ### *can_return_nil*
50
70
 
51
71
  By default it is expected that each controller action returns model or array of models. `nil` is not allowed. You can change that by adding `can_return_nil` like this:
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Povilas Jurčys']
10
10
  spec.email = ['po.jurcys@gmail.com']
11
11
 
12
- spec.summary = %q{GrapQL server and client for rails}
12
+ spec.summary = %q{GraphQL server and client for rails}
13
13
  spec.homepage = 'https://github.com/povilasjurcys/graphql_rails'
14
14
  spec.license = 'MIT'
15
15
 
data/lib/graphql_rails.rb CHANGED
@@ -4,6 +4,7 @@ require 'graphql_rails/version'
4
4
  require 'graphql_rails/model'
5
5
  require 'graphql_rails/router'
6
6
  require 'graphql_rails/controller'
7
+ require 'graphql_rails/attribute'
7
8
 
8
9
  # wonders starts here
9
10
  module GraphqlRails
@@ -1,56 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'graphql'
4
- require 'graphql_rails/type_parser'
4
+ require 'graphql_rails/attribute/attributable'
5
5
 
6
6
  module GraphqlRails
7
7
  # contains info about single graphql attribute
8
8
  class Attribute
9
- attr_reader :name, :graphql_field_type, :property, :type_name, :description
9
+ include Attributable
10
+
11
+ attr_reader :property, :description
10
12
 
11
13
  def initialize(name, type = nil, description: nil, property: name)
12
- @original_name = name.to_s
13
- @name = @original_name.tr('!', '')
14
- @type_name = type.to_s
15
- @graphql_field_type = parse_type(type || type_by_attribute_name)
14
+ @initial_type = type
15
+ @initial_name = name
16
16
  @description = description
17
17
  @property = property.to_s
18
18
  end
19
19
 
20
- def field_name
21
- field =
22
- if name.end_with?('?')
23
- "is_#{name.remove(/\?\Z/)}"
24
- else
25
- name
26
- end
27
-
28
- field.camelize(:lower)
29
- end
30
-
31
20
  def field_args
32
21
  [field_name, graphql_field_type, { property: property.to_sym, description: description }]
33
22
  end
34
23
 
35
- private
36
-
37
- attr_reader :original_name
24
+ protected
38
25
 
39
- def type_by_attribute_name
40
- case name
41
- when 'id', /_id\Z/
42
- GraphQL::ID_TYPE
43
- when /\?\Z/
44
- GraphQL::BOOLEAN_TYPE
45
- else
46
- GraphQL::STRING_TYPE
47
- end
48
- end
49
-
50
- def parse_type(type)
51
- type = TypeParser.new(type).graphql_type
52
-
53
- original_name['!'] ? type.to_non_null_type : type
54
- end
26
+ attr_reader :initial_type, :initial_name
55
27
  end
56
28
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails/attribute/type_parser'
4
+ require 'graphql_rails/attribute/attribute_name_parser'
5
+
6
+ module GraphqlRails
7
+ class Attribute
8
+ # contains methods which are shared between various attribute-like classes
9
+ # expects `initial_name` and `initial_type` to be defined
10
+ module Attributable
11
+ def field_name
12
+ attribute_name_parser.field_name
13
+ end
14
+
15
+ def type_name
16
+ @type_name ||= initial_type.to_s
17
+ end
18
+
19
+ def name
20
+ attribute_name_parser.name
21
+ end
22
+
23
+ def required?
24
+ attribute_name_parser.required? || !initial_type.to_s[/!$/].nil?
25
+ end
26
+
27
+ def graphql_model
28
+ type_parser.graphql_model
29
+ end
30
+
31
+ def graphql_field_type
32
+ @graphql_field_type ||= \
33
+ if required?
34
+ nullable_type.to_non_null_type
35
+ else
36
+ nullable_type
37
+ end
38
+ end
39
+
40
+ protected
41
+
42
+ def nullable_type
43
+ type = type_parser.graphql_type
44
+ type.non_null? ? type.of_type : type
45
+ end
46
+
47
+ private
48
+
49
+ def type_parser
50
+ @type_parser ||= TypeParser.new(initial_type || attribute_name_parser.graphql_type)
51
+ end
52
+
53
+ def attribute_name_parser
54
+ @attribute_name_parser ||= AttributeNameParser.new(initial_name)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ class Attribute
5
+ # Parses attribute name and can generates graphql scalar type,
6
+ # grapqhl name and etc. based on that
7
+ class AttributeNameParser
8
+ attr_reader :name
9
+
10
+ def initialize(original_name)
11
+ name = original_name.to_s
12
+ @required = !name['!'].nil?
13
+ @name = name.tr('!', '')
14
+ end
15
+
16
+ def field_name
17
+ @field_name ||= begin
18
+ field =
19
+ if name.end_with?('?')
20
+ "is_#{name.remove(/\?\Z/)}"
21
+ else
22
+ name
23
+ end
24
+
25
+ field.camelize(:lower)
26
+ end
27
+ end
28
+
29
+ def graphql_type
30
+ @graphql_type ||= \
31
+ case name
32
+ when 'id', /_id\Z/
33
+ GraphQL::ID_TYPE
34
+ when /\?\Z/
35
+ GraphQL::BOOLEAN_TYPE
36
+ else
37
+ GraphQL::STRING_TYPE
38
+ end
39
+ end
40
+
41
+ def required?
42
+ @required
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+
5
+ module GraphqlRails
6
+ class Attribute
7
+ # converts string value in to GraphQL type
8
+ class TypeParser
9
+ class UnknownTypeError < ArgumentError; end
10
+
11
+ TYPE_MAPPING = {
12
+ 'id' => GraphQL::ID_TYPE,
13
+
14
+ 'int' => GraphQL::INT_TYPE,
15
+ 'integer' => GraphQL::INT_TYPE,
16
+
17
+ 'string' => GraphQL::STRING_TYPE,
18
+ 'str' => GraphQL::STRING_TYPE,
19
+ 'text' => GraphQL::STRING_TYPE,
20
+ 'time' => GraphQL::STRING_TYPE,
21
+ 'date' => GraphQL::STRING_TYPE,
22
+
23
+ 'bool' => GraphQL::BOOLEAN_TYPE,
24
+ 'boolean' => GraphQL::BOOLEAN_TYPE,
25
+
26
+ 'float' => GraphQL::FLOAT_TYPE,
27
+ 'double' => GraphQL::FLOAT_TYPE,
28
+ 'decimal' => GraphQL::FLOAT_TYPE
29
+ }.freeze
30
+
31
+ def initialize(unparsed_type)
32
+ @unparsed_type = unparsed_type
33
+ end
34
+
35
+ def graphql_type
36
+ return unparsed_type if raw_graphql_type?
37
+
38
+ if list?
39
+ parsed_list_type
40
+ else
41
+ parsed_inner_type
42
+ end
43
+ end
44
+
45
+ def graphql_model
46
+ type_class = inner_type_name.safe_constantize
47
+ return unless type_class.respond_to?(:graphql)
48
+
49
+ type_class
50
+ end
51
+
52
+ private
53
+
54
+ attr_reader :unparsed_type
55
+
56
+ def parsed_list_type
57
+ list_type = parsed_inner_type.to_list_type
58
+
59
+ if required_list_type?
60
+ list_type.to_non_null_type
61
+ else
62
+ list_type
63
+ end
64
+ end
65
+
66
+ def parsed_inner_type
67
+ if required_inner_type?
68
+ type_by_name.to_non_null_type
69
+ else
70
+ type_by_name
71
+ end
72
+ end
73
+
74
+ def required_inner_type?
75
+ !!unparsed_type[/\w!/] # rubocop:disable Style/DoubleNegation
76
+ end
77
+
78
+ def list?
79
+ unparsed_type.to_s.include?(']')
80
+ end
81
+
82
+ def required_list_type?
83
+ unparsed_type.to_s.include?(']!')
84
+ end
85
+
86
+ def raw_graphql_type?
87
+ unparsed_type.is_a?(GraphQL::BaseType) ||
88
+ unparsed_type.is_a?(GraphQL::ObjectType) ||
89
+ unparsed_type.is_a?(GraphQL::InputObjectType) ||
90
+ (defined?(GraphQL::Schema::Member) && unparsed_type.is_a?(Class) && unparsed_type < GraphQL::Schema::Member)
91
+ end
92
+
93
+ def inner_type_name
94
+ unparsed_type.to_s.tr('[]!', '')
95
+ end
96
+
97
+ def type_by_name
98
+ TYPE_MAPPING.fetch(inner_type_name.downcase) do
99
+ dynamicly_defined_type || raise(
100
+ UnknownTypeError,
101
+ "Type #{unparsed_type.inspect} is not supported. Supported scalar types are: #{TYPE_MAPPING.keys}." \
102
+ ' All the classes that includes `GraphqlRails::Model` are also supported as types.'
103
+ )
104
+ end
105
+ end
106
+
107
+ def dynamicly_defined_type
108
+ type_class = graphql_model
109
+ return unless type_class
110
+
111
+ type_class.graphql.graphql_type
112
+ end
113
+ end
114
+ end
115
+ end
@@ -60,6 +60,7 @@ module GraphqlRails
60
60
 
61
61
  def default_type
62
62
  return default_collection_type if route.collection?
63
+
63
64
  default_inner_return_type
64
65
  end
65
66
 
@@ -104,6 +105,7 @@ module GraphqlRails
104
105
  [namespace, model_name].join('::').constantize
105
106
  rescue NameError => err
106
107
  raise unless err.message.match?(/uninitialized constant/)
108
+
107
109
  nil
108
110
  end
109
111
 
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/string/filters'
4
- require 'graphql_rails/type_parser'
4
+ require 'graphql_rails/attribute/type_parser'
5
5
  require 'graphql_rails/attribute'
6
+ require 'graphql_rails/model/input_attribute'
6
7
 
7
8
  module GraphqlRails
8
9
  class Controller
@@ -79,12 +80,12 @@ module GraphqlRails
79
80
  end
80
81
 
81
82
  def type_parser
82
- TypeParser.new(custom_return_type)
83
+ GraphqlRails::Attribute::TypeParser.new(custom_return_type)
83
84
  end
84
85
 
85
86
  def permit_attribute(name, type = nil)
86
87
  field_name = name.to_s.remove(/!\Z/)
87
- attributes[field_name] = Attribute.new(name.to_s, type)
88
+ attributes[field_name] = Model::InputAttribute.new(name.to_s, type)
88
89
  end
89
90
  end
90
91
  end
@@ -32,7 +32,7 @@ module GraphqlRails
32
32
  description(action.description)
33
33
 
34
34
  action.arguments.each do |attribute|
35
- argument(attribute.field_name, attribute.graphql_field_type)
35
+ argument(*attribute.function_argument_args)
36
36
  end
37
37
  end
38
38
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- # GrapqhQL error that is raised when invalid data is given
4
+ # GraphQL error that is raised when invalid data is given
5
5
  class ValidationError < ExecutionError
6
6
  attr_reader :short_message, :field
7
7
 
@@ -3,7 +3,7 @@
3
3
  require 'graphql_rails/model/configuration'
4
4
 
5
5
  module GraphqlRails
6
- # this module allows to convert any ruby class in to grapql type object
6
+ # this module allows to convert any ruby class in to graphql type object
7
7
  #
8
8
  # usage:
9
9
  # class YourModel
@@ -15,7 +15,7 @@ module GraphqlRails
15
15
  # end
16
16
  # end
17
17
  #
18
- # YourModel.new.grapql_type # => type with [:id, :title] attributes
18
+ # YourModel.new.graphql_type # => type with [:id, :title] attributes
19
19
  module Model
20
20
  def self.included(base)
21
21
  base.extend(ClassMethods)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ module Model
5
+ # contains methods which are shared between various configurations
6
+ # expects `default_name` to be defined
7
+ module Configurable
8
+ def attributes
9
+ @attributes ||= {}
10
+ end
11
+
12
+ def name(type_name = nil)
13
+ @name = type_name if type_name
14
+ @name || default_name
15
+ end
16
+
17
+ def description(new_description = nil)
18
+ @description = new_description if new_description
19
+ @description
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,12 +2,14 @@
2
2
 
3
3
  require 'graphql_rails/attribute'
4
4
  require 'graphql_rails/model/graphql_type_builder'
5
+ require 'graphql_rails/model/input'
6
+ require 'graphql_rails/model/configurable'
5
7
 
6
8
  module GraphqlRails
7
9
  module Model
8
10
  # stores information about model specific config, like attributes and types
9
11
  class Configuration
10
- attr_reader :attributes
12
+ include Configurable
11
13
 
12
14
  COUNT_TOTAL_ITEMS = lambda do |obj, _args, _ctx|
13
15
  obj_nodes = obj.nodes
@@ -17,17 +19,6 @@ module GraphqlRails
17
19
 
18
20
  def initialize(model_class)
19
21
  @model_class = model_class
20
- @attributes = {}
21
- end
22
-
23
- def name(type_name = nil)
24
- @name = type_name if type_name
25
- @name || name_by_class_name
26
- end
27
-
28
- def description(new_description = nil)
29
- @description = new_description if new_description
30
- @description
31
22
  end
32
23
 
33
24
  def attribute(attribute_name, type: nil, **attribute_options)
@@ -39,8 +30,22 @@ module GraphqlRails
39
30
  )
40
31
  end
41
32
 
33
+ def input(input_name = nil)
34
+ @input ||= {}
35
+ name = input_name.to_s
36
+
37
+ if block_given?
38
+ @input[name] ||= Model::Input.new(model_class, input_name)
39
+ yield(@input[name])
40
+ end
41
+
42
+ @input.fetch(name) do
43
+ raise("GraphQL input with name #{input_name.inspect} is not defined for #{model_class}")
44
+ end
45
+ end
46
+
42
47
  def graphql_type
43
- @graphql_type ||= GrapqhlTypeBuilder.new(
48
+ @graphql_type ||= GraphqlTypeBuilder.new(
44
49
  name: name, description: description, attributes: attributes
45
50
  ).call
46
51
  end
@@ -57,8 +62,8 @@ module GraphqlRails
57
62
 
58
63
  attr_reader :model_class
59
64
 
60
- def name_by_class_name
61
- @name_by_class_name ||= model_class.name.split('::').last
65
+ def default_name
66
+ @default_name ||= model_class.name.split('::').last
62
67
  end
63
68
  end
64
69
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ module Model
5
+ # stores information about model specific config, like attributes and types
6
+ class GraphqlInputTypeBuilder
7
+ def initialize(name:, description: nil, attributes:)
8
+ @name = name
9
+ @attributes = attributes
10
+ @description = description
11
+ end
12
+
13
+ def call
14
+ type_name = name
15
+ type_description = description
16
+ type_attributes = attributes
17
+
18
+ Class.new(GraphQL::Schema::InputObject) do
19
+ graphql_name(type_name)
20
+ description(type_description)
21
+
22
+ type_attributes.each_value do |type_attribute|
23
+ argument(*type_attribute.input_argument_args)
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :model_configuration, :attributes, :name, :description
31
+ end
32
+ end
33
+ end
@@ -3,7 +3,7 @@
3
3
  module GraphqlRails
4
4
  module Model
5
5
  # stores information about model specific config, like attributes and types
6
- class GrapqhlTypeBuilder
6
+ class GraphqlTypeBuilder
7
7
  def initialize(name:, description: nil, attributes:)
8
8
  @name = name
9
9
  @attributes = attributes
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails/model/graphql_input_type_builder'
4
+ require 'graphql_rails/model/configurable'
5
+
6
+ module GraphqlRails
7
+ module Model
8
+ # stores information about model input specific config, like attributes and types
9
+ class Input
10
+ include Configurable
11
+
12
+ def initialize(model_class, input_name_suffix)
13
+ @model_class = model_class
14
+ @input_name_suffix = input_name_suffix
15
+ end
16
+
17
+ def graphql_input_type
18
+ @graphql_input_type ||= GraphqlInputTypeBuilder.new(
19
+ name: name, description: description, attributes: attributes
20
+ ).call
21
+ end
22
+
23
+ def attribute(attribute_name, type: nil, **attribute_options)
24
+ attributes[attribute_name.to_s] = \
25
+ InputAttribute.new(
26
+ attribute_name,
27
+ type,
28
+ attribute_options
29
+ )
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :input_name_suffix, :model_class
35
+
36
+ def default_name
37
+ @default_name ||= begin
38
+ suffix = input_name_suffix ? input_name_suffix.to_s.tableize : ''
39
+ "#{model_class.name.split('::').last}#{suffix}Input"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ module Model
5
+ # contains info about single graphql input attribute
6
+ class InputAttribute
7
+ include GraphqlRails::Attribute::Attributable
8
+
9
+ attr_reader :description
10
+
11
+ def initialize(name, type = nil, description: nil)
12
+ @initial_name = name
13
+ @initial_type = type
14
+ @description = description
15
+ end
16
+
17
+ def function_argument_args
18
+ [field_name, graphql_input_type, { description: description }]
19
+ end
20
+
21
+ def input_argument_args
22
+ type = raw_input_type || model_input_type || nullable_type
23
+ [field_name, type, { required: required?, description: description }]
24
+ end
25
+
26
+ def graphql_input_type
27
+ raw_input_type || model_input_type || graphql_field_type
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :initial_name, :initial_type
33
+
34
+ def raw_input_type
35
+ return initial_type if initial_type.is_a?(GraphQL::InputObjectType)
36
+ return initial_type.graphql_input_type if initial_type.is_a?(Model::Input)
37
+ end
38
+
39
+ def model_input_type
40
+ return unless graphql_model
41
+
42
+ graphql_model.graphql.input.graphql_input_type
43
+ end
44
+ end
45
+ end
46
+ end
@@ -18,6 +18,7 @@ module GraphqlRails
18
18
 
19
19
  def path
20
20
  return relative_path if module_name.empty?
21
+
21
22
  [module_name, relative_path].join('/')
22
23
  end
23
24
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- VERSION = '0.4.3'
4
+ VERSION = '0.5.0'
5
5
  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.3
4
+ version: 0.5.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: 2019-03-19 00:00:00.000000000 Z
11
+ date: 2019-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -107,6 +107,7 @@ files:
107
107
  - ".rubocop.yml"
108
108
  - ".ruby-version"
109
109
  - ".travis.yml"
110
+ - CHANGELOG.md
110
111
  - CODE_OF_CONDUCT.md
111
112
  - Gemfile
112
113
  - Gemfile.lock
@@ -128,6 +129,9 @@ files:
128
129
  - graphql_rails.gemspec
129
130
  - lib/graphql_rails.rb
130
131
  - lib/graphql_rails/attribute.rb
132
+ - lib/graphql_rails/attribute/attributable.rb
133
+ - lib/graphql_rails/attribute/attribute_name_parser.rb
134
+ - lib/graphql_rails/attribute/type_parser.rb
131
135
  - lib/graphql_rails/controller.rb
132
136
  - lib/graphql_rails/controller/action.rb
133
137
  - lib/graphql_rails/controller/action_configuration.rb
@@ -141,8 +145,12 @@ files:
141
145
  - lib/graphql_rails/errors/execution_error.rb
142
146
  - lib/graphql_rails/errors/validation_error.rb
143
147
  - lib/graphql_rails/model.rb
148
+ - lib/graphql_rails/model/configurable.rb
144
149
  - lib/graphql_rails/model/configuration.rb
150
+ - lib/graphql_rails/model/graphql_input_type_builder.rb
145
151
  - lib/graphql_rails/model/graphql_type_builder.rb
152
+ - lib/graphql_rails/model/input.rb
153
+ - lib/graphql_rails/model/input_attribute.rb
146
154
  - lib/graphql_rails/router.rb
147
155
  - lib/graphql_rails/router/mutation_route.rb
148
156
  - lib/graphql_rails/router/query_route.rb
@@ -150,7 +158,6 @@ files:
150
158
  - lib/graphql_rails/router/route.rb
151
159
  - lib/graphql_rails/router/schema_builder.rb
152
160
  - lib/graphql_rails/rspec_controller_helpers.rb
153
- - lib/graphql_rails/type_parser.rb
154
161
  - lib/graphql_rails/version.rb
155
162
  homepage: https://github.com/povilasjurcys/graphql_rails
156
163
  licenses:
@@ -175,5 +182,5 @@ rubyforge_project:
175
182
  rubygems_version: 2.7.7
176
183
  signing_key:
177
184
  specification_version: 4
178
- summary: GrapQL server and client for rails
185
+ summary: GraphQL server and client for rails
179
186
  test_files: []
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'graphql'
4
-
5
- module GraphqlRails
6
- # converts string value in to GraphQL type
7
- class TypeParser
8
- class UnknownTypeError < ArgumentError; end
9
-
10
- TYPE_MAPPING = {
11
- 'id' => GraphQL::ID_TYPE,
12
-
13
- 'int' => GraphQL::INT_TYPE,
14
- 'integer' => GraphQL::INT_TYPE,
15
-
16
- 'string' => GraphQL::STRING_TYPE,
17
- 'str' => GraphQL::STRING_TYPE,
18
- 'text' => GraphQL::STRING_TYPE,
19
- 'time' => GraphQL::STRING_TYPE,
20
- 'date' => GraphQL::STRING_TYPE,
21
-
22
- 'bool' => GraphQL::BOOLEAN_TYPE,
23
- 'boolean' => GraphQL::BOOLEAN_TYPE,
24
-
25
- 'float' => GraphQL::FLOAT_TYPE,
26
- 'double' => GraphQL::FLOAT_TYPE,
27
- 'decimal' => GraphQL::FLOAT_TYPE
28
- }.freeze
29
-
30
- def initialize(unparsed_type)
31
- @unparsed_type = unparsed_type
32
- end
33
-
34
- def graphql_type
35
- return unparsed_type if raw_graphql_type?
36
-
37
- if list?
38
- parsed_list_type
39
- else
40
- parsed_inner_type
41
- end
42
- end
43
-
44
- def graphql_model
45
- type_class = inner_type_name.safe_constantize
46
- return unless type_class.respond_to?(:graphql)
47
- type_class
48
- end
49
-
50
- private
51
-
52
- attr_reader :unparsed_type
53
-
54
- def parsed_list_type
55
- list_type = parsed_inner_type.to_list_type
56
-
57
- if required_list_type?
58
- list_type.to_non_null_type
59
- else
60
- list_type
61
- end
62
- end
63
-
64
- def parsed_inner_type
65
- if required_inner_type?
66
- type_by_name.to_non_null_type
67
- else
68
- type_by_name
69
- end
70
- end
71
-
72
- def required_inner_type?
73
- !!unparsed_type[/\w!/] # rubocop:disable Style/DoubleNegation
74
- end
75
-
76
- def list?
77
- unparsed_type.to_s.include?(']')
78
- end
79
-
80
- def required_list_type?
81
- unparsed_type.to_s.include?(']!')
82
- end
83
-
84
- def raw_graphql_type?
85
- unparsed_type.is_a?(GraphQL::BaseType) ||
86
- unparsed_type.is_a?(GraphQL::ObjectType) ||
87
- (defined?(GraphQL::Schema::Member) && unparsed_type.is_a?(Class) && unparsed_type < GraphQL::Schema::Member)
88
- end
89
-
90
- def inner_type_name
91
- unparsed_type.to_s.tr('[]!', '')
92
- end
93
-
94
- def type_by_name
95
- TYPE_MAPPING.fetch(inner_type_name.downcase) do
96
- dynamicly_defined_type || raise(
97
- UnknownTypeError,
98
- "Type #{unparsed_type.inspect} is not supported. Supported scalar types are: #{TYPE_MAPPING.keys}." \
99
- ' All the classes that includes `GraphqlRails::Model` are also supported as types.'
100
- )
101
- end
102
- end
103
-
104
- def dynamicly_defined_type
105
- type_class = graphql_model
106
- return unless type_class
107
-
108
- type_class.graphql.graphql_type
109
- end
110
- end
111
- end