graphql_rails 0.4.3 → 0.5.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 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