graphql-decorate 0.1.1 → 0.2.1
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 +4 -4
- data/README.md +2 -1
- data/graphql-decorate.gemspec +2 -2
- data/lib/graphql/decorate.rb +5 -1
- data/lib/graphql/decorate/configuration.rb +1 -0
- data/lib/graphql/decorate/connection.rb +52 -0
- data/lib/graphql/decorate/field_context.rb +18 -0
- data/lib/graphql/decorate/field_extension.rb +10 -7
- data/lib/graphql/decorate/field_integration.rb +8 -4
- data/lib/graphql/decorate/{resolution.rb → object.rb} +14 -15
- data/lib/graphql/decorate/object_integration.rb +1 -0
- data/lib/graphql/decorate/type_attributes.rb +11 -1
- data/lib/graphql/decorate/version.rb +2 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e23e910653e03c46982bf8916ab3f15cde1be96a6436cabbf0271c40a11f1b4d
|
4
|
+
data.tar.gz: d71940ac1feabb05b64228812ad1768f8f4f288e2ff105a619ee8cd02b00ce8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 457e1cd6d2c62e5f463ccfacd8fa62f3e444c4b980d5e1d0b24b7b59aa960bcbf3c38cb0013055c793bafb3af86a5c0c2a68ae687b0c6af66de0b5b24b96d811
|
7
|
+
data.tar.gz: 678fb9bd85a0de6e6f0d336f2e812f91e1a326c7e3bff426159ff2bf2a83af5bc93bdf1b4ff490650f3a851f8d42b0370955d552bf57d22a47f183e8c2335462
|
data/README.md
CHANGED
@@ -131,7 +131,8 @@ end
|
|
131
131
|
### Collections
|
132
132
|
By default `graphql-decorate` recognizes `Array` and `ActiveRecord::Relation` object types and
|
133
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.
|
134
|
+
their elements decorated, you can add them in the configuration. Custom collection classes must
|
135
|
+
respond to `#map`.
|
135
136
|
```ruby
|
136
137
|
GraphQL::Decorate.configure do |config|
|
137
138
|
config.custom_collection_classes = [Mongoid::Relations::Targets::Enumerable]
|
data/graphql-decorate.gemspec
CHANGED
@@ -7,10 +7,10 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "graphql-decorate"
|
8
8
|
spec.version = GraphQL::Decorate::VERSION
|
9
9
|
spec.authors = ["Ben Brook"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["bbrook154@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = 'A decorator integration for the GraphQL gem'
|
13
|
-
spec.homepage = 'https://
|
13
|
+
spec.homepage = 'https://www.github.com/TrueCar/graphql-decorate'
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
# Specify which files should be added to the gem when it is released.
|
data/lib/graphql/decorate.rb
CHANGED
@@ -4,10 +4,14 @@ require_relative 'decorate/configuration'
|
|
4
4
|
require_relative 'decorate/object_integration'
|
5
5
|
require_relative 'decorate/field_integration'
|
6
6
|
require_relative 'decorate/field_extension'
|
7
|
-
require_relative 'decorate/
|
7
|
+
require_relative 'decorate/object'
|
8
8
|
require_relative 'decorate/type_attributes'
|
9
|
+
require_relative 'decorate/field_context'
|
10
|
+
require_relative 'decorate/connection'
|
9
11
|
|
12
|
+
# Matching the graphql-ruby namespace
|
10
13
|
module GraphQL
|
14
|
+
# Entry point for graphql-decorate. Handles configuration.
|
11
15
|
module Decorate
|
12
16
|
# @return [Configuration] Returns a new instance of GraphQL::Decorate::Configuration.
|
13
17
|
def self.configuration
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Decorate
|
4
|
+
# Wraps a GraphQL::Pagination::Connection object to decorate values after pagination is applied.
|
5
|
+
class Connection
|
6
|
+
# @return [GraphQL::Pagination::Connection] Connection being decorated
|
7
|
+
attr_reader :connection
|
8
|
+
|
9
|
+
# @return [GraphQL::Decorate::FieldContext] Current field context
|
10
|
+
attr_reader :field_context
|
11
|
+
|
12
|
+
def initialize(connection, field_context)
|
13
|
+
@connection = connection
|
14
|
+
@field_context = field_context
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Array] Decorated nodes after pagination is applied
|
18
|
+
def nodes
|
19
|
+
nodes = @connection.nodes
|
20
|
+
nodes.map { |node| GraphQL::Decorate::Object.new(node, field_context).decorate }
|
21
|
+
end
|
22
|
+
|
23
|
+
# @see nodes
|
24
|
+
# @return [Array] Decorated nodes after pagination is applied
|
25
|
+
def edge_nodes
|
26
|
+
nodes
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
private
|
31
|
+
|
32
|
+
def method_missing(symbol, *args, &block)
|
33
|
+
@connection.class.send(symbol, *args, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def respond_to_missing?(method, include_private = false)
|
37
|
+
@connection.class.respond_to_missing(method, include_private)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def method_missing(symbol, *args, &block)
|
44
|
+
@connection.send(symbol, *args, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def respond_to_missing?(method, include_private = false)
|
48
|
+
@connection.respond_to_missing(method, include_private)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Decorate
|
4
|
+
# Wraps current GraphQL::Query::Context and options provided to a field for portability.
|
5
|
+
class FieldContext
|
6
|
+
# @return [GraphQL::Query::Context] Current GraphQL query context
|
7
|
+
attr_reader :context
|
8
|
+
|
9
|
+
# @return [Hash] Options provided to the field being decorated
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
def initialize(context, options)
|
13
|
+
@context = context
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,19 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
module Decorate
|
4
|
+
# Extension run after fields are resolved to decorate their value.
|
4
5
|
class FieldExtension < GraphQL::Schema::FieldExtension
|
5
6
|
# Extension to be called after lazy loading.
|
6
7
|
# @param context [GraphQL::Query::Context] The current GraphQL query context.
|
7
8
|
# @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
|
+
# @return [::Object, GraphQL::Decorate::Connection] Decorated object.
|
9
10
|
def after_resolve(context:, value:, **_rest)
|
10
11
|
return if value.nil?
|
11
12
|
|
12
|
-
|
13
|
-
if
|
14
|
-
|
13
|
+
field_context = GraphQL::Decorate::FieldContext.new(context, options)
|
14
|
+
if value.is_a?(GraphQL::Pagination::Connection)
|
15
|
+
GraphQL::Decorate::Connection.new(value, field_context)
|
16
|
+
elsif collection_classes.any? { |c| value.is_a?(c) }
|
17
|
+
value.map { |item| decorate(item, field_context) }
|
15
18
|
else
|
16
|
-
decorate(value,
|
19
|
+
decorate(value, field_context)
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
@@ -25,8 +28,8 @@ module GraphQL
|
|
25
28
|
klasses
|
26
29
|
end
|
27
30
|
|
28
|
-
def decorate(object,
|
29
|
-
GraphQL::Decorate::
|
31
|
+
def decorate(object, field_context)
|
32
|
+
GraphQL::Decorate::Object.new(object, field_context).decorate
|
30
33
|
end
|
31
34
|
end
|
32
35
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module GraphQL
|
2
2
|
module Decorate
|
3
|
+
# Extends default field behavior and adds extension to the field if it should be decorated.
|
3
4
|
module FieldIntegration
|
4
5
|
# Overridden field initializer
|
5
6
|
# @param type [GraphQL::Schema::Object] The type to add the extension to.
|
@@ -15,6 +16,8 @@ module GraphQL
|
|
15
16
|
|
16
17
|
def get_extension_options(type)
|
17
18
|
type_attributes = GraphQL::Decorate::TypeAttributes.new(type)
|
19
|
+
return unless type_attributes.decorator_class
|
20
|
+
|
18
21
|
{
|
19
22
|
decorator_class: type_attributes.decorator_class,
|
20
23
|
decorator_evaluator: type_attributes.decorator_evaluator,
|
@@ -24,10 +27,11 @@ module GraphQL
|
|
24
27
|
end
|
25
28
|
|
26
29
|
def extend_with_decorator(options)
|
27
|
-
|
28
|
-
|
29
|
-
@extensions.
|
30
|
-
@extensions.
|
30
|
+
extension(GraphQL::Decorate::FieldExtension, options)
|
31
|
+
# ext = GraphQL::Decorate::FieldExtension.new(field: self, options: options)
|
32
|
+
# @extensions = @extensions.dup
|
33
|
+
# @extensions.unshift(ext)
|
34
|
+
# @extensions.freeze
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
module Decorate
|
4
|
-
|
5
|
-
|
6
|
-
# @param
|
7
|
-
# @param
|
8
|
-
def initialize(object,
|
4
|
+
# Handles decorating an object given its current field context.
|
5
|
+
class Object
|
6
|
+
# @param object [Object] Object being decorated.
|
7
|
+
# @param field_context [GraphQL::Decorate::FieldContext] Current GraphQL field context and options.
|
8
|
+
def initialize(object, field_context)
|
9
9
|
@object = object
|
10
|
-
@
|
11
|
-
@extension_options = extension_options
|
10
|
+
@field_context = field_context
|
12
11
|
@default_decorator_context = { graphql: true }
|
13
12
|
end
|
14
13
|
|
15
14
|
# Resolve the object with decoration.
|
16
15
|
# @return [Object] Decorated object if possible, otherwise the original object.
|
17
|
-
def
|
16
|
+
def decorate
|
18
17
|
if decorator_class
|
19
18
|
GraphQL::Decorate.configuration.evaluate_decorator.call(decorator_class, object, decorator_context)
|
20
19
|
else
|
@@ -24,20 +23,20 @@ module GraphQL
|
|
24
23
|
|
25
24
|
private
|
26
25
|
|
27
|
-
attr_reader :object, :
|
26
|
+
attr_reader :object, :field_context, :default_decorator_context
|
28
27
|
|
29
28
|
def decorator_class
|
30
|
-
if
|
31
|
-
|
32
|
-
elsif
|
33
|
-
|
29
|
+
if field_context.options[:decorator_class]
|
30
|
+
field_context.options[:decorator_class]
|
31
|
+
elsif field_context.options[:decorator_evaluator]
|
32
|
+
field_context.options[:decorator_evaluator].call(object)
|
34
33
|
else
|
35
34
|
resolve_decorator_class
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
38
|
def decorator_context_evaluator
|
40
|
-
|
39
|
+
field_context.options[:decorator_context_evaluator] || resolve_decorator_context_evaluator
|
41
40
|
end
|
42
41
|
|
43
42
|
private
|
@@ -65,7 +64,7 @@ module GraphQL
|
|
65
64
|
end
|
66
65
|
|
67
66
|
def resolve_type
|
68
|
-
|
67
|
+
field_context.options[:unresolved_type]&.resolve_type(object, field_context.context)
|
69
68
|
end
|
70
69
|
end
|
71
70
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module GraphQL
|
2
2
|
module Decorate
|
3
|
+
# Extends GraphQL::Schema::Object classes with methods to set the desired decorator class and context.
|
3
4
|
module ObjectIntegration
|
4
5
|
# Decorate the type with a decorator class.
|
5
6
|
# @param klass [Class] Class the object should be decorated with.
|
@@ -1,37 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
module Decorate
|
4
|
+
# Extracts configured decorator attributes from a GraphQL::Schema::Object type.
|
4
5
|
class TypeAttributes
|
6
|
+
# @return [GraphQL::Schema::Object] type to extract decorator attributes from
|
5
7
|
attr_reader :type
|
6
8
|
|
9
|
+
# @param [GraphQL::Schema::Object] type to extract decorator attributes from
|
7
10
|
def initialize(type)
|
8
11
|
@type = type
|
9
12
|
end
|
10
13
|
|
14
|
+
# @return [Class, nil] Decorator class for the type if available
|
11
15
|
def decorator_class
|
12
16
|
get_attribute(:decorator_class)
|
13
17
|
end
|
14
18
|
|
19
|
+
# @return [Proc, nil] Decorator evaluator for the type if available
|
15
20
|
def decorator_evaluator
|
16
21
|
get_attribute(:decorator_evaluator)
|
17
22
|
end
|
18
23
|
|
24
|
+
# @return [Proc, nil] Decorator context evaluator for the type if available
|
19
25
|
def decorator_context_evaluator
|
20
26
|
get_attribute(:decorator_context_evaluator)
|
21
27
|
end
|
22
28
|
|
29
|
+
# @return [GraphQL::Schema::Object, nil] Decorator evaluator for the type if available
|
23
30
|
def unresolved_type
|
24
31
|
unresolved_type? ? type : nil
|
25
32
|
end
|
26
33
|
|
34
|
+
# @return [Boolean] True if type is not yet resolved, false if it is resolved
|
27
35
|
def unresolved_type?
|
28
36
|
type.respond_to?(:resolve_type)
|
29
37
|
end
|
30
38
|
|
39
|
+
# @return [Boolean] True if type is resolved, false if it is not resolved
|
31
40
|
def resolved_type?
|
32
41
|
!unresolved_type?
|
33
42
|
end
|
34
43
|
|
44
|
+
# @return [Boolean] True if type is a connection, false if it is resolved
|
35
45
|
def connection?
|
36
46
|
resolved_type? && type.respond_to?(:node_type)
|
37
47
|
end
|
@@ -42,7 +52,7 @@ module GraphQL
|
|
42
52
|
if connection?
|
43
53
|
type.node_type.respond_to?(name) && type.node_type.public_send(name)
|
44
54
|
elsif resolved_type?
|
45
|
-
type.respond_to?(name)
|
55
|
+
type.respond_to?(name) ? type.public_send(name) : nil
|
46
56
|
end
|
47
57
|
end
|
48
58
|
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: 0.
|
4
|
+
version: 0.2.1
|
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-02-
|
11
|
+
date: 2021-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
version: '3.0'
|
75
75
|
description:
|
76
76
|
email:
|
77
|
-
-
|
77
|
+
- bbrook154@gmail.com
|
78
78
|
executables: []
|
79
79
|
extensions: []
|
80
80
|
extra_rdoc_files: []
|
@@ -91,13 +91,15 @@ files:
|
|
91
91
|
- graphql-decorate.gemspec
|
92
92
|
- lib/graphql/decorate.rb
|
93
93
|
- lib/graphql/decorate/configuration.rb
|
94
|
+
- lib/graphql/decorate/connection.rb
|
95
|
+
- lib/graphql/decorate/field_context.rb
|
94
96
|
- lib/graphql/decorate/field_extension.rb
|
95
97
|
- lib/graphql/decorate/field_integration.rb
|
98
|
+
- lib/graphql/decorate/object.rb
|
96
99
|
- lib/graphql/decorate/object_integration.rb
|
97
|
-
- lib/graphql/decorate/resolution.rb
|
98
100
|
- lib/graphql/decorate/type_attributes.rb
|
99
101
|
- lib/graphql/decorate/version.rb
|
100
|
-
homepage: https://
|
102
|
+
homepage: https://www.github.com/TrueCar/graphql-decorate
|
101
103
|
licenses:
|
102
104
|
- MIT
|
103
105
|
metadata: {}
|