graphql-decorate 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eebb3163d3b156e31469281fed745c5512628d8d53bac95d14a482d5973eba3f
4
- data.tar.gz: cf29b63e882f792f0b862b311b7dbc1f52b5be1d0685863afeeb0a11e7bb5dd6
3
+ metadata.gz: e23e910653e03c46982bf8916ab3f15cde1be96a6436cabbf0271c40a11f1b4d
4
+ data.tar.gz: d71940ac1feabb05b64228812ad1768f8f4f288e2ff105a619ee8cd02b00ce8a
5
5
  SHA512:
6
- metadata.gz: 1d14eee9d8590363f51582f8d199ea8f89b6f7af6d7391097839c43ac3573830b68eb81937b0e73645bfffc21caa2188ee187d979c2b25637872a171d504b0c9
7
- data.tar.gz: 3dd3cfeabf0b687aa4fc80e91779378b113b9b56145f6a172ca0930bc954511fba709266f62f552d257fd65b76d8b66b7bb1e6aaf211ef497ac2fbc8ce066e66
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]
@@ -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 = ["bbrook@truecar.com"]
10
+ spec.email = ["bbrook154@gmail.com"]
11
11
 
12
12
  spec.summary = 'A decorator integration for the GraphQL gem'
13
- spec.homepage = 'https://git.corp.tc/bbrook/graphql-decorate'
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.
@@ -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/resolution'
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
@@ -1,5 +1,6 @@
1
1
  module GraphQL
2
2
  module Decorate
3
+ # Allows overriding default decoration and custom collection class behavior.
3
4
  class Configuration
4
5
  # @return [Proc] Proc that decorates a given object and context with a given decorator class.
5
6
  attr_reader :evaluate_decorator
@@ -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
- collection = collection_classes.any? { |c| value.is_a?(c) }
13
- if collection
14
- value.map { |item| decorate(item, context) }
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, context)
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, context)
29
- GraphQL::Decorate::Resolution.new(object, context, options).resolve
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
- ext = GraphQL::Decorate::FieldExtension.new(field: self, options: options)
28
- @extensions = @extensions.dup
29
- @extensions.unshift(ext)
30
- @extensions.freeze
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
- 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)
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
- @graphql_context = graphql_context
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 resolve
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, :graphql_context, :extension_options, :default_decorator_context
26
+ attr_reader :object, :field_context, :default_decorator_context
28
27
 
29
28
  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)
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
- extension_options[:decorator_context_evaluator] || resolve_decorator_context_evaluator
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
- extension_options[:unresolved_type]&.resolve_type(object, graphql_context)
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) && type.public_send(name)
55
+ type.respond_to?(name) ? type.public_send(name) : nil
46
56
  end
47
57
  end
48
58
  end
@@ -1,5 +1,6 @@
1
1
  module GraphQL
2
2
  module Decorate
3
- VERSION = "0.1.1"
3
+ # Current version number
4
+ VERSION = "0.2.1"
4
5
  end
5
6
  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.1.1
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-26 00:00:00.000000000 Z
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
- - bbrook@truecar.com
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://git.corp.tc/bbrook/graphql-decorate
102
+ homepage: https://www.github.com/TrueCar/graphql-decorate
101
103
  licenses:
102
104
  - MIT
103
105
  metadata: {}