graphql-decorate 0.1.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 +7 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +14 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +147 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/graphql-decorate.gemspec +30 -0
- data/lib/graphql/decorate.rb +27 -0
- data/lib/graphql/decorate/configuration.rb +24 -0
- data/lib/graphql/decorate/field_extension.rb +33 -0
- data/lib/graphql/decorate/field_integration.rb +34 -0
- data/lib/graphql/decorate/object_integration.rb +40 -0
- data/lib/graphql/decorate/resolution.rb +72 -0
- data/lib/graphql/decorate/type_attributes.rb +50 -0
- data/lib/graphql/decorate/version.rb +5 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5fc5dae438847027d85bbbad840e06d7e988262d131942f22896ef6eccc0bc37
|
4
|
+
data.tar.gz: c3a678357eba0122ae55d4a9b810bc157b496c8116c4156ca6c215f39379b0c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 377a02d6883de6e5ae2508fc8f157a16c53beb1ea219e058e6a06b9b692176a1ea808046f156b99c8cd9aa1f8f0462be5b0f5adf2eb57eac3a70f28b255f8089
|
7
|
+
data.tar.gz: 182faddf5c006dd2518accbfd87f6be489b700d467412d3f8016748b0a60370f082ddad47572097518f57b0b15185cde07144d8a111396c5efa55eaa9b99ccac
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
23
|
+
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- name: Set up Ruby
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
+
# uses: ruby/setup-ruby@v1
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rake
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 bbrook
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# GraphQL Decorate
|
2
|
+
|
3
|
+
`graphql-decorate` adds an easy-to-use interface for decorating types in `graphql-ruby`. It lets
|
4
|
+
you move logic out of your type files and keep them declarative.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'graphql-decorate'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install graphql-decorate
|
21
|
+
|
22
|
+
Once the gem is installed, you need to add the integrations to your base type and field classes.
|
23
|
+
```ruby
|
24
|
+
class BaseType < GraphQL::Schema::Object
|
25
|
+
extend GraphQL::Decorate::ObjectIntegration
|
26
|
+
end
|
27
|
+
|
28
|
+
class BaseField < GraphQL::Schema::Field
|
29
|
+
include GraphQL::Decorate::FieldIntegration
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
### Basic use case
|
36
|
+
```ruby
|
37
|
+
class Rectangle
|
38
|
+
attr_reader :length
|
39
|
+
|
40
|
+
def initialize(length)
|
41
|
+
@length = length
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class RectangleDecorator < BaseDecorator
|
46
|
+
def area
|
47
|
+
length * 2
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Rectangle < GraphQL::Schema::Object
|
52
|
+
decorate_with RectangleDecorator
|
53
|
+
|
54
|
+
field :area, Int, null: false
|
55
|
+
end
|
56
|
+
```
|
57
|
+
In this example, the `Rectangle` type is being decorated with a `RectangleDecorator`. Whenever a
|
58
|
+
`Rectangle` gets resolved in the graph, the underlying object will be wrapped with a
|
59
|
+
`RectangleDecorator`. All of the methods on the decorator are accessible on the type.
|
60
|
+
|
61
|
+
### Decorators
|
62
|
+
By default, `graphql-decorate` is set up to work with Draper-style decorators. These decorators
|
63
|
+
provide a `decorate` method that wraps the original object and returns an instance of the
|
64
|
+
decorator. They can also take in an additional context hash.
|
65
|
+
```ruby
|
66
|
+
RectangleDecorator.decorate(rectangle, context)
|
67
|
+
```
|
68
|
+
If you are using a different decorator pattern then you can override this default behavior in
|
69
|
+
the configuration.
|
70
|
+
```ruby
|
71
|
+
GraphQL::Decorate.configure do |config|
|
72
|
+
config.decorate do |decorator_class, object, _context|
|
73
|
+
decorator_class.decorate_differently(object)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
### Types
|
79
|
+
Three methods are made available on your type classes
|
80
|
+
#### decorate_with
|
81
|
+
`decorate_with` accepts a decorator class that will decorate every instance of your type.
|
82
|
+
```ruby
|
83
|
+
class Rectangle < GraphQL::Schema::Object
|
84
|
+
decorate_with RectangleDecorator
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
#### decorate_when
|
89
|
+
`decorate_when` accepts a block which yields the underlying object. If you have multiple
|
90
|
+
possible decorator classes you can return the one intended for the underling object.
|
91
|
+
```ruby
|
92
|
+
class Rectangle < GraphQL::Schema::Object
|
93
|
+
decorate_when do |object|
|
94
|
+
if object.length == object.width
|
95
|
+
SquareDecorator
|
96
|
+
else
|
97
|
+
RectangleDecorator
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
#### decorator_context
|
104
|
+
`decorator_context` accepts a block which yields the underlying object. If your decorator pattern
|
105
|
+
allows additional context being passed into the decorators, you can define it here.
|
106
|
+
```ruby
|
107
|
+
class Rectangle < GraphQL::Schema::Object
|
108
|
+
decorator_context do |object|
|
109
|
+
{
|
110
|
+
name: object.name
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
`RectangleDecorator` will be initialized with a context of `{ name: <object_name> }`.
|
116
|
+
|
117
|
+
#### Combinations
|
118
|
+
You can mix and match these methods to suit your needs. Note that if `decorate_with` and
|
119
|
+
`decorate_when` are both provided that `decorate_with` will take precedence.
|
120
|
+
```ruby
|
121
|
+
class Rectangle < GraphQL::Schema::Object
|
122
|
+
decorate_with RectangleDecorator
|
123
|
+
decorator_context do |object|
|
124
|
+
{
|
125
|
+
name: object.name
|
126
|
+
}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
### Collections
|
132
|
+
By default `graphql-decorate` recognizes `Array` and `ActiveRecord::Relation` object types and
|
133
|
+
decorates every element in the collection. If you have other collection types that should have
|
134
|
+
their elements decorated, you can add them in the configuration.
|
135
|
+
```ruby
|
136
|
+
GraphQL::Decorate.configure do |config|
|
137
|
+
config.custom_collection_classes = [Mongoid::Relations::Targets::Enumerable]
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
## Development
|
142
|
+
|
143
|
+
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.
|
144
|
+
|
145
|
+
## License
|
146
|
+
|
147
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "graphql/decorate"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "graphql/decorate/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "graphql-decorate"
|
8
|
+
spec.version = GraphQL::Decorate::VERSION
|
9
|
+
spec.authors = ["Ben Brook"]
|
10
|
+
spec.email = ["bbrook@truecar.com"]
|
11
|
+
|
12
|
+
spec.summary = 'A decorator integration for the GraphQL gem'
|
13
|
+
spec.homepage = 'https://git.corp.tc/bbrook/graphql-decorate'
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Specify which files should be added to the gem when it is released.
|
17
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
19
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_runtime_dependency "graphql", ">= 1.3", "< 2"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", ">= 2"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'graphql'
|
2
|
+
require_relative 'decorate/version'
|
3
|
+
require_relative 'decorate/configuration'
|
4
|
+
require_relative 'decorate/object_integration'
|
5
|
+
require_relative 'decorate/field_integration'
|
6
|
+
require_relative 'decorate/field_extension'
|
7
|
+
require_relative 'decorate/resolution'
|
8
|
+
require_relative 'decorate/type_attributes'
|
9
|
+
|
10
|
+
module GraphQL
|
11
|
+
module Decorate
|
12
|
+
# @return [Configuration] Returns a new instance of GraphQL::Decorate::Configuration.
|
13
|
+
def self.configuration
|
14
|
+
@configuration ||= Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# @yield [configuration] Gives the configuration to the block.
|
18
|
+
def self.configure
|
19
|
+
yield(configuration)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Configuration] Resets the configuration to its defaults.
|
23
|
+
def self.reset_configuration!
|
24
|
+
@configuration = Configuration.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module Decorate
|
3
|
+
class Configuration
|
4
|
+
# @return [Proc] Proc that decorates a given object and context with a given decorator class.
|
5
|
+
attr_reader :evaluate_decorator
|
6
|
+
|
7
|
+
# @return [Array] Controls which classes are treated as collections to be decorated.
|
8
|
+
attr_accessor :custom_collection_classes
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@evaluate_decorator = lambda do |decorator_class, object, context|
|
12
|
+
decorator_class.decorate(object, context: context)
|
13
|
+
end
|
14
|
+
@custom_collection_classes = []
|
15
|
+
end
|
16
|
+
|
17
|
+
# @yield [decorator_class, object, decorator_context] Override default decoration behavior with the given block.
|
18
|
+
# @return [Void]
|
19
|
+
def decorate(&block)
|
20
|
+
@evaluate_decorator = block
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Decorate
|
4
|
+
class FieldExtension < GraphQL::Schema::FieldExtension
|
5
|
+
# Extension to be called after lazy loading.
|
6
|
+
# @param context [GraphQL::Query::Context] The current GraphQL query context.
|
7
|
+
# @param value [Object, GraphQL::Schema::Object] The object being decorated. Can be a schema object if the field hasn't been resolved yet.
|
8
|
+
# @return [Object] Decorated object.
|
9
|
+
def after_resolve(context:, value:, **_rest)
|
10
|
+
return if value.nil?
|
11
|
+
|
12
|
+
collection = collection_classes.any? { |c| value.is_a?(c) }
|
13
|
+
if collection
|
14
|
+
value.map { |item| decorate(item, context) }
|
15
|
+
else
|
16
|
+
decorate(value, context)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def collection_classes
|
23
|
+
klasses = [Array] + GraphQL::Decorate.configuration.custom_collection_classes
|
24
|
+
klasses << ::ActiveRecord::Relation if defined?(ActiveRecord::Relation)
|
25
|
+
klasses
|
26
|
+
end
|
27
|
+
|
28
|
+
def decorate(object, context)
|
29
|
+
GraphQL::Decorate::Resolution.new(object, context, options).resolve
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module Decorate
|
3
|
+
module FieldIntegration
|
4
|
+
# Overridden field initializer
|
5
|
+
# @param type [GraphQL::Schema::Object] The type to add the extension to.
|
6
|
+
# @return [Void]
|
7
|
+
def initialize(type:, **rest, &block)
|
8
|
+
super
|
9
|
+
field_type = [type].flatten(1).first
|
10
|
+
extension_options = get_extension_options(field_type)
|
11
|
+
extend_with_decorator(extension_options) if extension_options
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def get_extension_options(type)
|
17
|
+
type_attributes = GraphQL::Decorate::TypeAttributes.new(type)
|
18
|
+
{
|
19
|
+
decorator_class: type_attributes.decorator_class,
|
20
|
+
decorator_evaluator: type_attributes.decorator_evaluator,
|
21
|
+
decorator_context_evaluator: type_attributes.decorator_context_evaluator,
|
22
|
+
unresolved_type: type_attributes.unresolved_type
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def extend_with_decorator(options)
|
27
|
+
ext = GraphQL::Decorate::FieldExtension.new(field: self, options: options)
|
28
|
+
@extensions = @extensions.dup
|
29
|
+
@extensions.unshift(ext)
|
30
|
+
@extensions.freeze
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module Decorate
|
3
|
+
module ObjectIntegration
|
4
|
+
# Decorate the type with a decorator class.
|
5
|
+
# @param klass [Class] Class the object should be decorated with.
|
6
|
+
def decorate_with(klass)
|
7
|
+
@decorator_class = klass
|
8
|
+
end
|
9
|
+
|
10
|
+
# Dynamically choose the decorator class based on the underlying object.
|
11
|
+
# @yield [object] Gives the underlying object to the block.
|
12
|
+
# @return [Proc] Proc to evaluate decorator class. Proc should return a decorator class.
|
13
|
+
def decorate_when(&block)
|
14
|
+
@decorator_evaluator = block
|
15
|
+
end
|
16
|
+
|
17
|
+
# Pass additional data to the decorator context (if supported).
|
18
|
+
# @yield [object] Gives the underlying object to the block.
|
19
|
+
# @return [Proc] Proc to evaluate decorator context. Proc should return Hash.
|
20
|
+
def decorator_context(&block)
|
21
|
+
@decorator_context_evaluator = block
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Class, nil] Gets the currently set decorator class.
|
25
|
+
def decorator_class
|
26
|
+
@decorator_class
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Proc, nil] Gets the currently set decorator evaluator.
|
30
|
+
def decorator_evaluator
|
31
|
+
@decorator_evaluator
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Proc, nil] Gets the currently set decorator context evaluator.
|
35
|
+
def decorator_context_evaluator
|
36
|
+
@decorator_context_evaluator
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Decorate
|
4
|
+
class Resolution
|
5
|
+
# @param object [Object] Object being resolved.
|
6
|
+
# @param graphql_context [GraphQL::Query::Context] CurrentGraphQL query context.
|
7
|
+
# @param extension_options [Hash] Options provided from the field extension.
|
8
|
+
def initialize(object, graphql_context, extension_options)
|
9
|
+
@object = object
|
10
|
+
@graphql_context = graphql_context
|
11
|
+
@extension_options = extension_options
|
12
|
+
@default_decorator_context = { graphql: true }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Resolve the object with decoration.
|
16
|
+
# @return [Object] Decorated object if possible, otherwise the original object.
|
17
|
+
def resolve
|
18
|
+
if decorator_class
|
19
|
+
GraphQL::Decorate.configuration.evaluate_decorator.call(decorator_class, object, decorator_context)
|
20
|
+
else
|
21
|
+
object
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :object, :graphql_context, :extension_options, :default_decorator_context
|
28
|
+
|
29
|
+
def decorator_class
|
30
|
+
if extension_options[:decorator_class]
|
31
|
+
extension_options[:decorator_class]
|
32
|
+
elsif extension_options[:decorator_evaluator]
|
33
|
+
extension_options[:decorator_evaluator].call(object)
|
34
|
+
else
|
35
|
+
resolve_decorator_class
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def decorator_context_evaluator
|
40
|
+
extension_options[:decorator_context_evaluator] || resolve_decorator_context_evaluator
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def evaluate_decoration_context
|
46
|
+
decorator_context_evaluator ? decorator_context_evaluator.call(object) : {}
|
47
|
+
end
|
48
|
+
|
49
|
+
def decorator_context
|
50
|
+
evaluate_decoration_context.merge(default_decorator_context)
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolve_decorator_class
|
54
|
+
type = resolve_type
|
55
|
+
if type.respond_to?(:decorator_class) && type.decorator_class
|
56
|
+
type.decorator_class
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def resolve_decorator_context_evaluator
|
61
|
+
type = resolve_type
|
62
|
+
if type.respond_to?(:decorator_context_evaluator) && type.decorator_context_evaluator
|
63
|
+
type.decorator_context_evaluator
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def resolve_type
|
68
|
+
extension_options[:unresolved_type]&.resolve_type(object, graphql_context)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Decorate
|
4
|
+
class TypeAttributes
|
5
|
+
attr_reader :type
|
6
|
+
|
7
|
+
def initialize(type)
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def decorator_class
|
12
|
+
get_attribute(:decorator_class)
|
13
|
+
end
|
14
|
+
|
15
|
+
def decorator_evaluator
|
16
|
+
get_attribute(:decorator_evaluator)
|
17
|
+
end
|
18
|
+
|
19
|
+
def decorator_context_evaluator
|
20
|
+
get_attribute(:decorator_context_evaluator)
|
21
|
+
end
|
22
|
+
|
23
|
+
def unresolved_type
|
24
|
+
unresolved_type? ? type : nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def unresolved_type?
|
28
|
+
type.respond_to?(:resolve_type)
|
29
|
+
end
|
30
|
+
|
31
|
+
def resolved_type?
|
32
|
+
!unresolved_type?
|
33
|
+
end
|
34
|
+
|
35
|
+
def connection?
|
36
|
+
resolved_type? && type.respond_to?(:node_type)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def get_attribute(name)
|
42
|
+
if connection?
|
43
|
+
type.node_type.respond_to?(name) && type.node_type.public_send(name)
|
44
|
+
elsif resolved_type?
|
45
|
+
type.respond_to?(name) && type.public_send(name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphql-decorate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Brook
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: graphql
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '10.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '10.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
75
|
+
description:
|
76
|
+
email:
|
77
|
+
- bbrook@truecar.com
|
78
|
+
executables: []
|
79
|
+
extensions: []
|
80
|
+
extra_rdoc_files: []
|
81
|
+
files:
|
82
|
+
- ".github/workflows/ruby.yml"
|
83
|
+
- ".gitignore"
|
84
|
+
- Gemfile
|
85
|
+
- LICENSE.txt
|
86
|
+
- README.md
|
87
|
+
- Rakefile
|
88
|
+
- bin/console
|
89
|
+
- bin/setup
|
90
|
+
- graphql-decorate.gemspec
|
91
|
+
- lib/graphql/decorate.rb
|
92
|
+
- lib/graphql/decorate/configuration.rb
|
93
|
+
- lib/graphql/decorate/field_extension.rb
|
94
|
+
- lib/graphql/decorate/field_integration.rb
|
95
|
+
- lib/graphql/decorate/object_integration.rb
|
96
|
+
- lib/graphql/decorate/resolution.rb
|
97
|
+
- lib/graphql/decorate/type_attributes.rb
|
98
|
+
- lib/graphql/decorate/version.rb
|
99
|
+
homepage: https://git.corp.tc/bbrook/graphql-decorate
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubygems_version: 3.2.11
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: A decorator integration for the GraphQL gem
|
122
|
+
test_files: []
|