graphql-decorate 1.0.0 → 1.0.3

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: f51b30fb5841e235310b83ab3d9b697d86b420c1a807bb0500b73dcf231d295b
4
- data.tar.gz: 4c02e6130d6955d6d9fbde06a9fe45352e1bd7f5dba7ec7e1d60c9bb846242c0
3
+ metadata.gz: 332c718984dda5295c80630808cc5f03f89eac5ba0395edfb4642ab0d757aeda
4
+ data.tar.gz: e7eb062bb4effd0083c8a329697d4410e4ae968444294608ff5b90bd2304534f
5
5
  SHA512:
6
- metadata.gz: 2aaa588eb463291941b8c4678daaaead6479b2526d9799998889186cccece07770cded6ec469108e2b92346317ab804fed0e7fd24acb80679251b2e0cb63dc43
7
- data.tar.gz: 1c2a48487fd6b82739b501968578f039c89e7769db849daf955f152b72ec2e353b43790ea159400580f0e99f8b464c7a8f7cd98e11b7bd7a818ce42df7b2299f
6
+ metadata.gz: 6d37cc0239dbcfda3424d59102b658756c2660ddc72c4e719da8eb5e6b56a60c0c72c5bb3d7e53d1870bc669848a4e4cc3ff49105e8ece6c3ec19d3a5ebb4ad1
7
+ data.tar.gz: b0227888e6b2d7cc8ab394e60b5e99bef9e1421fc57209ac7fca70aae5b078439d4e8b1bfee7e67d12d6e817ce2412562e9376278849e28aaeed851c71726759
@@ -1,4 +1,4 @@
1
- name: Ruby
1
+ name: CI
2
2
 
3
3
  on:
4
4
  push:
@@ -7,7 +7,7 @@ on:
7
7
  branches: [ master ]
8
8
 
9
9
  jobs:
10
- test:
10
+ ci:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
@@ -28,12 +28,6 @@ jobs:
28
28
  - name: Run RuboCop
29
29
  run: bundle exec rubocop
30
30
 
31
- - name: Upload coverage results
32
- uses: actions/upload-artifact@master
33
- with:
34
- name: coverage-report
35
- path: coverage
36
-
37
31
  - name: Check documentation completion
38
32
  run: |
39
33
  completion_percentage=$(bundle exec yard | tee /dev/stdout | tail -1 | cut -d'%' -f1 | xargs)
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Gem Version](https://badge.fury.io/rb/graphql-decorate.svg)](https://badge.fury.io/rb/graphql-decorate)
2
+ ![CI](https://github.com/TrueCar/graphql-decorate/actions/workflows/ci.yml/badge.svg)
3
+
1
4
  # GraphQL Decorate
2
5
 
3
6
  `graphql-decorate` adds an easy-to-use interface for decorating types in [`graphql-ruby`](https://github.com/rmosolgo/graphql-ruby). It lets
@@ -19,16 +22,19 @@ Or install it yourself as:
19
22
 
20
23
  $ gem install graphql-decorate
21
24
 
22
- Once the gem is installed, you need to add the integrations to your base type and field classes.
25
+ Once the gem is installed, you need to add the plugin to your schema and the integration into
26
+ your base object class.
23
27
  ```ruby
24
- class BaseType < GraphQL::Schema::Object
25
- extend GraphQL::Decorate::ObjectIntegration
28
+ class Schema < GraphQL::Schema
29
+ use GraphQL::Decorate
26
30
  end
27
31
 
28
- class BaseField < GraphQL::Schema::Field
29
- include GraphQL::Decorate::FieldIntegration
32
+ class BaseObject < GraphQL::Schema::Object
33
+ include GraphQL::Decorate::ObjectIntegration
30
34
  end
31
35
  ```
36
+ Note that `use GraphQL::Decorate` must be included in the schema _after_ `query` and `mutation`
37
+ so that the fields to be extended are initialized first.
32
38
 
33
39
  ## Usage
34
40
 
@@ -48,7 +54,7 @@ class RectangleDecorator < BaseDecorator
48
54
  end
49
55
  end
50
56
 
51
- class Rectangle < GraphQL::Schema::Object
57
+ class RectangleType < BaseObject
52
58
  decorate_with RectangleDecorator
53
59
 
54
60
  field :area, Int, null: false
@@ -78,8 +84,7 @@ end
78
84
  ### Types
79
85
  Two methods are made available on your type classes: `decorate_with` and `decorate_metadata`.
80
86
  Every method that yields the underlying object will also yield the current GraphQL `context`.
81
- If decoration depends on some context in the current query then you can access it when the field
82
- is resolved.
87
+ If decoration depends on some context in the current query then you can access it when the field is resolved.
83
88
 
84
89
  #### decorate_with
85
90
  `decorate_with` accepts a decorator class that will decorate every instance of your type.
@@ -117,17 +122,17 @@ to return `Hash`s.
117
122
  ```ruby
118
123
  class Rectangle < GraphQL::Schema::Object
119
124
  decorate_metadata do |metadata|
120
- metadata.unscoped do |object, _graphql_context|
121
- {
122
- name: object.name
123
- }
124
- end
125
+ metadata.unscoped do |object, _graphql_context|
126
+ {
127
+ name: object.name
128
+ }
129
+ end
125
130
 
126
- metadata.scoped do |object, _graphql_context|
127
- {
128
- inside_rectangle: true
129
- }
130
- end
131
+ metadata.scoped do |object, _graphql_context|
132
+ {
133
+ inside_rectangle: true
134
+ }
135
+ end
131
136
  end
132
137
  end
133
138
  ```
@@ -142,7 +147,7 @@ You can mix and match these methods to suit your needs. Note that if `unscoped`
142
147
  class Rectangle < GraphQL::Schema::Object
143
148
  decorate_with RectangleDecorator
144
149
  decorate_metadata do |metadata|
145
- metadata.scoped do |object, _graphql_context|
150
+ metadata.scoped do |object, _graphql_context|
146
151
  {
147
152
  name: object.name
148
153
  }
@@ -4,20 +4,24 @@ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'graphql/decorate/version'
6
6
 
7
+ # rubocop:disable Metrics/BlockLength
7
8
  Gem::Specification.new do |spec|
8
- spec.name = 'graphql-decorate'
9
- spec.version = GraphQL::Decorate::VERSION
10
- spec.authors = ['Ben Brook']
11
- spec.email = ['bbrook154@gmail.com']
9
+ spec.name = 'graphql-decorate'
10
+ spec.version = GraphQL::Decorate::VERSION
11
+ spec.authors = ['Ben Brook']
12
+ spec.email = ['bbrook154@gmail.com']
12
13
 
13
- spec.summary = 'A decorator integration for the GraphQL gem'
14
- spec.homepage = 'https://www.github.com/TrueCar/graphql-decorate'
15
- spec.license = 'MIT'
14
+ spec.summary = 'A decorator integration for the GraphQL gem'
15
+ spec.homepage = 'https://www.github.com/TrueCar/graphql-decorate'
16
+ spec.license = 'MIT'
17
+ spec.metadata = {
18
+ 'rubygems_mfa_required' => 'true'
19
+ }
16
20
 
17
21
  # Specify which files should be added to the gem when it is released.
18
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added
19
23
  # into git.
20
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
25
  `git ls-files -z`.split("\x0").reject do |f|
22
26
  f.match(%r{^(test|spec|features)/})
23
27
  end
@@ -28,13 +32,14 @@ Gem::Specification.new do |spec|
28
32
 
29
33
  spec.required_ruby_version = '>= 2.6.0'
30
34
 
31
- spec.add_runtime_dependency 'graphql', '>= 1.3', '< 2'
35
+ spec.add_runtime_dependency 'graphql', '>= 1.3'
32
36
 
33
37
  spec.add_development_dependency 'bundler', '>= 2'
34
- spec.add_development_dependency 'rake', '~> 10.0'
38
+ spec.add_development_dependency 'rake', '>= 12.3.3'
35
39
  spec.add_development_dependency 'rspec', '~> 3.0'
36
40
  spec.add_development_dependency 'rubocop', ' >= 1.11.0 '
37
41
  spec.add_development_dependency 'rubocop-rspec', '2.2.0'
38
42
  spec.add_development_dependency 'simplecov', '~> 0.21.2'
39
43
  spec.add_development_dependency 'yard', '~> 0.9.26'
40
44
  end
45
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Allows extraction of a type class from a particular field.
4
+ module ExtractType
5
+ private
6
+
7
+ def extract_type(field)
8
+ if field.respond_to?(:of_type)
9
+ extract_type(field.of_type)
10
+ else
11
+ field
12
+ end
13
+ end
14
+ end
@@ -4,35 +4,35 @@ module GraphQL
4
4
  module Decorate
5
5
  # Extension run after fields are resolved to decorate their value.
6
6
  class FieldExtension < GraphQL::Schema::FieldExtension
7
+ include ExtractType
8
+
7
9
  # Extension to be called after lazy loading.
8
10
  # @param context [GraphQL::Query::Context] The current GraphQL query context.
9
- # @param value [Object, GraphQL::Schema::Object, GraphQL::Pagination::Connection] The object being decorated. Can
11
+ # @param value [Object, Array, GraphQL::Schema::Object] The object being decorated. Can
10
12
  # be a schema object if the field hasn't been resolved yet or a connection.
11
- # @param object [Object] Object the field is being resolved on.
12
- # @return [Object, GraphQL::Decorate::ConnectionWrapper] Decorated object.
13
- def after_resolve(context:, value:, object:, **_rest)
13
+ # @return [Object] Decorated object.
14
+ def after_resolve(context:, value:, **_rest)
14
15
  return if value.nil?
15
16
 
16
- resolve_decorated_value(value, object, context)
17
+ resolve_decorated_value(value, context)
17
18
  end
18
19
 
19
20
  private
20
21
 
21
- def resolve_decorated_value(value, parent_object, context)
22
+ def resolve_decorated_value(value, context)
22
23
  type = extract_type(context.to_h[:current_field].type)
23
- if value.is_a?(GraphQL::Pagination::Connection)
24
- GraphQL::Decorate::ConnectionWrapper.wrap(value, type, context)
25
- elsif collection?(value)
26
- value.map do |item|
27
- decorate(item, type, parent_object.object, parent_object.class, context)
24
+
25
+ if collection?(value)
26
+ value.each_with_index.map do |item, index|
27
+ decorate(item, type, context, index)
28
28
  end
29
29
  else
30
- decorate(value, type, parent_object.object, parent_object.class, context)
30
+ decorate(value, type, context)
31
31
  end
32
32
  end
33
33
 
34
- def decorate(value, type, parent_object, parent_type, context)
35
- undecorated_field = GraphQL::Decorate::UndecoratedField.new(value, type, parent_object, parent_type, context)
34
+ def decorate(value, type, context, index = nil)
35
+ undecorated_field = GraphQL::Decorate::UndecoratedField.new(value, type, context, index)
36
36
  GraphQL::Decorate::Decoration.decorate(undecorated_field)
37
37
  end
38
38
 
@@ -45,14 +45,6 @@ module GraphQL
45
45
  klasses << ::ActiveRecord::Relation if defined?(ActiveRecord::Relation)
46
46
  klasses
47
47
  end
48
-
49
- def extract_type(field)
50
- if field.respond_to?(:of_type)
51
- extract_type(field.of_type)
52
- else
53
- field
54
- end
55
- end
56
48
  end
57
49
  end
58
50
  end
@@ -4,6 +4,12 @@ module GraphQL
4
4
  module Decorate
5
5
  # Extends GraphQL::Schema::Object classes with methods to set the desired decorator class and context.
6
6
  module ObjectIntegration
7
+ # @param base [Class] Base class the module is being included in
8
+ # @return [nil]
9
+ def self.included(base)
10
+ base.extend(self)
11
+ end
12
+
7
13
  # Decorate the type with a decorator class.
8
14
  # @param klass [Class] Class the object should be decorated with.
9
15
  def decorate_with(klass = nil, &block)
@@ -39,7 +39,7 @@ module GraphQL
39
39
 
40
40
  # @return [Boolean] True if type is not yet resolved, false if it is resolved
41
41
  def unresolved_type?
42
- type.respond_to?(:resolve_type)
42
+ type.respond_to?(:kind) && [GraphQL::TypeKinds::INTERFACE, GraphQL::TypeKinds::UNION].include?(type.kind)
43
43
  end
44
44
 
45
45
  # @return [Boolean] True if type is resolved, false if it is not resolved
@@ -47,19 +47,10 @@ module GraphQL
47
47
  !unresolved_type?
48
48
  end
49
49
 
50
- # @return [Boolean] True if type is a connection, false if it is resolved
51
- def connection?
52
- resolved_type? && type.respond_to?(:node_type)
53
- end
54
-
55
50
  private
56
51
 
57
52
  def get_attribute(name)
58
- if connection?
59
- type.node_type.respond_to?(name) && type.node_type.public_send(name)
60
- elsif resolved_type?
61
- type.respond_to?(name) ? type.public_send(name) : nil
62
- end
53
+ type.respond_to?(name) ? type.public_send(name) : nil
63
54
  end
64
55
  end
65
56
  end
@@ -9,16 +9,15 @@ module GraphQL
9
9
 
10
10
  # @param value [Object] Value to be decorated
11
11
  # @param type [GraphQL::Schema::Object] Type class of value to be decorated
12
- # @param parent_value [Object] Value of the parent field
13
- # @param parent_type [GraphQL::Schema::Object] Type class of the parent field
14
12
  # @param graphql_context [GraphQL::Query::Context] Current query graphql_context
15
- def initialize(value, type, parent_value, parent_type, graphql_context)
13
+ def initialize(value, type, graphql_context, index = nil)
16
14
  @value = value
15
+ @type = type
17
16
  @type_attributes = GraphQL::Decorate::TypeAttributes.new(type)
18
- @parent_value = parent_value
19
- @parent_type = parent_type
20
17
  @graphql_context = graphql_context
21
18
  @default_metadata = { graphql: true }
19
+ @path = graphql_context[:current_path].dup
20
+ @path << index if index
22
21
  end
23
22
 
24
23
  # @return [Class] Decorator class for the current field
@@ -37,34 +36,44 @@ module GraphQL
37
36
 
38
37
  private
39
38
 
40
- attr_reader :type_attributes, :graphql_context, :parent_value, :parent_type, :default_metadata
39
+ attr_reader :type, :type_attributes, :graphql_context, :default_metadata, :path
41
40
 
42
41
  def unscoped_metadata
43
42
  unscoped_metadata_proc&.call(value, graphql_context) || {}
44
43
  end
45
44
 
46
45
  def scoped_metadata
47
- merged_scoped_metadata = existing_scoped_metadata.merge(new_scoped_metadata)
48
- graphql_context.scoped_set!(:scoped_decorator_metadata, merged_scoped_metadata)
49
- merged_scoped_metadata
46
+ insert_scoped_metadata(new_scoped_metadata)
50
47
  end
51
48
 
52
49
  def new_scoped_metadata
53
- scoped_metadata = scoped_metadata_proc&.call(value, graphql_context) || {}
54
- parent_scoped_metadata.merge(scoped_metadata)
55
- end
56
-
57
- def parent_scoped_metadata
58
- parent_type_attributes.decorator_metadata&.scoped_proc&.call(parent_value, graphql_context) || {}
59
- end
60
-
61
- def parent_type_attributes
62
- GraphQL::Decorate::TypeAttributes.new(parent_type)
63
- end
50
+ scoped_metadata_proc&.call(value, graphql_context) || {}
51
+ end
52
+
53
+ # rubocop:disable Metrics/AbcSize
54
+ def insert_scoped_metadata(metadata)
55
+ # Save metadata at each level in the path of the current execution.
56
+ # If a field's direct parent does not have metadata then it will
57
+ # use the next highest metadata in the tree that matches its path.
58
+ scoped_metadata = graphql_context[:scoped_decorator_metadata] ||= {}
59
+ prev_value = {}
60
+
61
+ path[0...-1].each do |step|
62
+ # Write the parent's metadata to the child if it doesn't already exist
63
+ scoped_metadata[step] = { value: prev_value, children: {} } unless scoped_metadata[step]
64
+ # Update the next parent's metadata to include anything at the current level
65
+ prev_value = prev_value.merge(scoped_metadata[step][:value])
66
+ # Move to the child fields and repeat
67
+ scoped_metadata = scoped_metadata[step][:children]
68
+ end
64
69
 
65
- def existing_scoped_metadata
66
- graphql_context[:scoped_decorator_metadata] || {}
70
+ # The last step in the path is the current field, merge in new metadata from
71
+ # the field itself and return it.
72
+ merged_metadata = { value: prev_value.merge(metadata), children: {} }
73
+ scoped_metadata[path[-1]] = merged_metadata
74
+ merged_metadata[:value]
67
75
  end
76
+ # rubocop:enable Metrics/AbcSize
68
77
 
69
78
  def unscoped_metadata_proc
70
79
  type_attributes.decorator_metadata&.unscoped_proc || resolve_unscoped_proc
@@ -91,11 +100,14 @@ module GraphQL
91
100
  end
92
101
 
93
102
  def resolved_type_attributes
94
- @resolved_type_attributes ||= begin
95
- if type_attributes.unresolved_type?
96
- GraphQL::Decorate::TypeAttributes.new(type_attributes.type.resolve_type(value, graphql_context))
97
- end
98
- end
103
+ @resolved_type_attributes ||= if type_attributes.unresolved_type?
104
+ if type.respond_to?(:resolve_type)
105
+ GraphQL::Decorate::TypeAttributes.new(type.resolve_type(value,
106
+ graphql_context))
107
+ else
108
+ graphql_context.schema.resolve_type(type, value, graphql_context)
109
+ end
110
+ end
99
111
  end
100
112
  end
101
113
  end
@@ -3,6 +3,6 @@
3
3
  module GraphQL
4
4
  module Decorate
5
5
  # Current version number
6
- VERSION = '1.0.0'
6
+ VERSION = '1.0.3'
7
7
  end
8
8
  end
@@ -3,19 +3,20 @@
3
3
  require 'graphql'
4
4
  require_relative 'decorate/version'
5
5
  require_relative 'decorate/configuration'
6
+ require_relative 'decorate/extract_type'
6
7
  require_relative 'decorate/object_integration'
7
- require_relative 'decorate/field_integration'
8
8
  require_relative 'decorate/field_extension'
9
9
  require_relative 'decorate/decoration'
10
10
  require_relative 'decorate/type_attributes'
11
11
  require_relative 'decorate/undecorated_field'
12
- require_relative 'decorate/connection_wrapper'
13
12
  require_relative 'decorate/metadata'
14
13
 
15
14
  # Matching the graphql-ruby namespace
16
15
  module GraphQL
17
16
  # Entry point for graphql-decorate. Handles configuration.
18
17
  module Decorate
18
+ extend ExtractType
19
+
19
20
  # @return [Configuration] Returns a new instance of GraphQL::Decorate::Configuration.
20
21
  def self.configuration
21
22
  @configuration ||= Configuration.new
@@ -30,5 +31,19 @@ module GraphQL
30
31
  def self.reset_configuration!
31
32
  @configuration = Configuration.new
32
33
  end
34
+
35
+ # @param schema_defn [GraphQL::Schema] Current schema class
36
+ # @return [nil]
37
+ def self.use(schema_defn)
38
+ schema_defn.types.each do |_name, type|
39
+ next unless type.respond_to?(:fields)
40
+
41
+ type.fields.each do |_name, field|
42
+ field_type = extract_type(field.type)
43
+ type_attributes = GraphQL::Decorate::TypeAttributes.new(field_type)
44
+ field.extension(GraphQL::Decorate::FieldExtension) if type_attributes.decoratable?
45
+ end
46
+ end
47
+ end
33
48
  end
34
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-decorate
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Brook
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-10 00:00:00.000000000 Z
11
+ date: 2022-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '2'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.3'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '2'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: bundler
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -48,16 +42,16 @@ dependencies:
48
42
  name: rake
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
- - - "~>"
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
- version: '10.0'
47
+ version: 12.3.3
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
- - - "~>"
52
+ - - ">="
59
53
  - !ruby/object:Gem::Version
60
- version: '10.0'
54
+ version: 12.3.3
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: rspec
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -135,8 +129,8 @@ executables: []
135
129
  extensions: []
136
130
  extra_rdoc_files: []
137
131
  files:
132
+ - ".github/workflows/ci.yml"
138
133
  - ".github/workflows/gem-push-on-release.yml"
139
- - ".github/workflows/ruby.yml"
140
134
  - ".gitignore"
141
135
  - ".rubocop.yml"
142
136
  - Gemfile
@@ -148,10 +142,9 @@ files:
148
142
  - graphql-decorate.gemspec
149
143
  - lib/graphql/decorate.rb
150
144
  - lib/graphql/decorate/configuration.rb
151
- - lib/graphql/decorate/connection_wrapper.rb
152
145
  - lib/graphql/decorate/decoration.rb
146
+ - lib/graphql/decorate/extract_type.rb
153
147
  - lib/graphql/decorate/field_extension.rb
154
- - lib/graphql/decorate/field_integration.rb
155
148
  - lib/graphql/decorate/metadata.rb
156
149
  - lib/graphql/decorate/object_integration.rb
157
150
  - lib/graphql/decorate/type_attributes.rb
@@ -160,7 +153,8 @@ files:
160
153
  homepage: https://www.github.com/TrueCar/graphql-decorate
161
154
  licenses:
162
155
  - MIT
163
- metadata: {}
156
+ metadata:
157
+ rubygems_mfa_required: 'true'
164
158
  post_install_message:
165
159
  rdoc_options: []
166
160
  require_paths:
@@ -176,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
170
  - !ruby/object:Gem::Version
177
171
  version: '0'
178
172
  requirements: []
179
- rubygems_version: 3.0.3
173
+ rubygems_version: 3.0.3.1
180
174
  signing_key:
181
175
  specification_version: 4
182
176
  summary: A decorator integration for the GraphQL gem
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- module Decorate
5
- # Wraps a GraphQL::Pagination::ConnectionWrapper object to decorate values after pagination is applied.
6
- class ConnectionWrapper
7
- # @param connection [GraphQL::Pagination::Connection] ConnectionWrapper being decorated
8
- # @param node_type [GraphQL::Schema::Object] Type class of the connection's node
9
- # @param context [GraphQL::Query::Context] Current query context
10
- def self.wrap(connection, node_type, context)
11
- @connection_class = connection.class
12
- new(connection, node_type, context)
13
- end
14
-
15
- # @return [GraphQL::Pagination::Connection] ConnectionWrapper being decorated
16
- attr_reader :connection
17
-
18
- # @param connection [GraphQL::Pagination::Connection] ConnectionWrapper being decorated
19
- # # @param node_type [GraphQL::Schema::Object] Type class of the connection's node
20
- # @param context [GraphQL::Query::Context] Current query context
21
- def initialize(connection, node_type, context)
22
- @connection = connection
23
- @node_type = node_type
24
- @context = context
25
- end
26
-
27
- # @return [Array] Decorated nodes after pagination is applied
28
- def nodes
29
- nodes = @connection.nodes
30
- nodes.map do |node|
31
- unresolved_field = GraphQL::Decorate::UndecoratedField.new(node, node_type, connection.parent,
32
- connection.field.owner, context)
33
- GraphQL::Decorate::Decoration.decorate(unresolved_field)
34
- end
35
- end
36
-
37
- # @see nodes
38
- # @return [Array] Decorated nodes after pagination is applied
39
- def edge_nodes
40
- nodes
41
- end
42
-
43
- class << self
44
- private
45
-
46
- def method_missing(symbol, *args, &block)
47
- @connection_class.send(symbol, *args, &block) || super
48
- end
49
-
50
- def respond_to_missing?(method, include_private = false)
51
- @connection_class.respond_to?(method, include_private)
52
- end
53
- end
54
-
55
- private
56
-
57
- attr_reader :node_type, :context
58
-
59
- def method_missing(symbol, *args, &block)
60
- @connection.send(symbol, *args, &block) || super
61
- end
62
-
63
- def respond_to_missing?(method, include_private = false)
64
- @connection.respond_to?(method, include_private)
65
- end
66
- end
67
- end
68
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- module Decorate
5
- # Extends default field behavior and adds extension to the field if it should be decorated.
6
- module FieldIntegration
7
- # Overridden field initializer
8
- # @param type [GraphQL::Schema::Object] The type to add the extension to.
9
- # @return [Void]
10
- def initialize(type:, **rest, &block)
11
- super
12
- field_type = [type].flatten(1).first
13
- type_attributes = GraphQL::Decorate::TypeAttributes.new(field_type)
14
- extension(GraphQL::Decorate::FieldExtension) if type_attributes.decoratable?
15
- end
16
- end
17
- end
18
- end