graphql-decorate 1.0.0 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/{ruby.yml → ci.yml} +2 -8
- data/README.md +24 -19
- data/graphql-decorate.gemspec +15 -10
- data/lib/graphql/decorate/extract_type.rb +14 -0
- data/lib/graphql/decorate/field_extension.rb +14 -22
- data/lib/graphql/decorate/object_integration.rb +6 -0
- data/lib/graphql/decorate/type_attributes.rb +2 -11
- data/lib/graphql/decorate/undecorated_field.rb +39 -27
- data/lib/graphql/decorate/version.rb +1 -1
- data/lib/graphql/decorate.rb +17 -2
- metadata +11 -17
- data/lib/graphql/decorate/connection_wrapper.rb +0 -68
- data/lib/graphql/decorate/field_integration.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 332c718984dda5295c80630808cc5f03f89eac5ba0395edfb4642ab0d757aeda
|
4
|
+
data.tar.gz: e7eb062bb4effd0083c8a329697d4410e4ae968444294608ff5b90bd2304534f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d37cc0239dbcfda3424d59102b658756c2660ddc72c4e719da8eb5e6b56a60c0c72c5bb3d7e53d1870bc669848a4e4cc3ff49105e8ece6c3ec19d3a5ebb4ad1
|
7
|
+
data.tar.gz: b0227888e6b2d7cc8ab394e60b5e99bef9e1421fc57209ac7fca70aae5b078439d4e8b1bfee7e67d12d6e817ce2412562e9376278849e28aaeed851c71726759
|
@@ -1,4 +1,4 @@
|
|
1
|
-
name:
|
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
|
-
|
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
|
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
|
25
|
-
|
28
|
+
class Schema < GraphQL::Schema
|
29
|
+
use GraphQL::Decorate
|
26
30
|
end
|
27
31
|
|
28
|
-
class
|
29
|
-
include GraphQL::Decorate::
|
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
|
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
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
+
metadata.unscoped do |object, _graphql_context|
|
126
|
+
{
|
127
|
+
name: object.name
|
128
|
+
}
|
129
|
+
end
|
125
130
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
-
|
150
|
+
metadata.scoped do |object, _graphql_context|
|
146
151
|
{
|
147
152
|
name: object.name
|
148
153
|
}
|
data/graphql-decorate.gemspec
CHANGED
@@ -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
|
9
|
-
spec.version
|
10
|
-
spec.authors
|
11
|
-
spec.email
|
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
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
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
|
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'
|
35
|
+
spec.add_runtime_dependency 'graphql', '>= 1.3'
|
32
36
|
|
33
37
|
spec.add_development_dependency 'bundler', '>= 2'
|
34
|
-
spec.add_development_dependency 'rake', '
|
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
|
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
|
-
# @
|
12
|
-
|
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,
|
17
|
+
resolve_decorated_value(value, context)
|
17
18
|
end
|
18
19
|
|
19
20
|
private
|
20
21
|
|
21
|
-
def resolve_decorated_value(value,
|
22
|
+
def resolve_decorated_value(value, context)
|
22
23
|
type = extract_type(context.to_h[:current_field].type)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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,
|
30
|
+
decorate(value, type, context)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def decorate(value, type,
|
35
|
-
undecorated_field = GraphQL::Decorate::UndecoratedField.new(value, type,
|
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?(:
|
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
|
-
|
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,
|
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 :
|
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
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
66
|
-
|
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 ||=
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
data/lib/graphql/decorate.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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:
|
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
|