hq-graphql 2.0.10 → 2.1.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.
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hq/graphql/inputs"
4
+ require "hq/graphql/mutation"
5
+ require "hq/graphql/types"
6
+
7
+ module HQ
8
+ module GraphQL
9
+ module Resource
10
+ module AutoMutation
11
+ def build_create
12
+ scoped_self = self
13
+
14
+ build_mutation(action: :create) do
15
+ define_method(:resolve) do |**args|
16
+ resource = scoped_self.new_record(context)
17
+ resource.assign_attributes(args[:attributes].format_nested_attributes)
18
+ if resource.save
19
+ {
20
+ resource: resource,
21
+ errors: {},
22
+ }
23
+ else
24
+ {
25
+ resource: nil,
26
+ errors: errors_from_resource(resource)
27
+ }
28
+ end
29
+ end
30
+
31
+ lazy_load do
32
+ argument :attributes, ::HQ::GraphQL::Inputs[scoped_self.model_name], required: true
33
+ end
34
+ end
35
+ end
36
+
37
+ def build_update
38
+ scoped_self = self
39
+
40
+ build_mutation(action: :update, require_primary_key: true) do
41
+ define_method(:resolve) do |**args|
42
+ resource = scoped_self.find_record(args, context)
43
+
44
+ if resource
45
+ resource.assign_attributes(args[:attributes].format_nested_attributes)
46
+ if resource.save
47
+ {
48
+ resource: resource,
49
+ errors: {},
50
+ }
51
+ else
52
+ {
53
+ resource: nil,
54
+ errors: errors_from_resource(resource)
55
+ }
56
+ end
57
+ else
58
+ {
59
+ resource: nil,
60
+ errors: { resource: "Unable to find #{self.class.graphql_name}" }
61
+ }
62
+ end
63
+ end
64
+
65
+ lazy_load do
66
+ argument :attributes, ::HQ::GraphQL::Inputs[scoped_self.model_name], required: true
67
+ end
68
+ end
69
+ end
70
+
71
+ def build_copy
72
+ scoped_self = self
73
+
74
+ build_mutation(action: :copy, require_primary_key: true, nil_klass: true) do
75
+ define_method(:resolve) do |**args|
76
+ resource = scoped_self.find_record(args, context)
77
+
78
+ if resource
79
+ copy = resource.copy
80
+ if copy.save
81
+ {
82
+ resource: copy,
83
+ errors: {},
84
+ }
85
+ else
86
+ {
87
+ resource: copy,
88
+ errors: errors_from_resource(copy)
89
+ }
90
+ end
91
+ else
92
+ {
93
+ resource: nil,
94
+ errors: { resource: "Unable to find #{self.class.graphql_name}" }
95
+ }
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ def build_destroy
102
+ scoped_self = self
103
+
104
+ build_mutation(action: :destroy, require_primary_key: true) do
105
+ define_method(:resolve) do |**attrs|
106
+ resource = scoped_self.find_record(attrs, context)
107
+
108
+ if resource
109
+ if resource.destroy
110
+ {
111
+ resource: resource,
112
+ errors: {},
113
+ }
114
+ else
115
+ {
116
+ resource: nil,
117
+ errors: errors_from_resource(resource)
118
+ }
119
+ end
120
+ else
121
+ {
122
+ resource: nil,
123
+ errors: { resource: "Unable to find #{self.class.graphql_name}" }
124
+ }
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ def build_mutation(action:, require_primary_key: false, nil_klass: false, &block)
131
+ gql_name = "#{graphql_name}#{action.to_s.titleize}"
132
+ scoped_model_name = model_name
133
+ Class.new(::HQ::GraphQL::Mutation) do
134
+ graphql_name gql_name
135
+
136
+ define_method(:ready?) do |*args|
137
+ super(*args) && ::HQ::GraphQL.authorized?(action, scoped_model_name, context)
138
+ end
139
+
140
+ lazy_load do
141
+ field :errors, ::HQ::GraphQL::Types::Object, null: false
142
+ field :resource, ::HQ::GraphQL::Types[scoped_model_name, nil_klass], null: true
143
+ end
144
+
145
+ instance_eval(&block)
146
+
147
+ if require_primary_key
148
+ lazy_load do
149
+ klass = scoped_model_name.constantize
150
+ primary_key = klass.primary_key
151
+ argument primary_key, ::GraphQL::Types::ID, required: true
152
+ end
153
+ end
154
+
155
+ def errors_from_resource(resource)
156
+ resource.errors.to_h.deep_transform_keys { |k| k.to_s.camelize(:lower) }
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -7,7 +7,7 @@ module HQ
7
7
  super
8
8
  base.class_eval do
9
9
  lazy_load do
10
- ::HQ::GraphQL.types.each do |type|
10
+ ::HQ::GraphQL.resources.each do |type|
11
11
  type.mutation_klasses.each do |mutation_name, klass|
12
12
  field mutation_name, mutation: klass
13
13
  end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "hq/graphql/types/object"
4
+ require "hq/graphql/types/uuid"
5
+
3
6
  module HQ
4
7
  module GraphQL
5
8
  module Types
@@ -10,7 +13,7 @@ module HQ
10
13
  def self.registry
11
14
  @registry ||= Hash.new do |hash, options|
12
15
  klass, nil_klass = Array(options)
13
- hash[klass] = nil_klass ? nil_query_klass(klass) : klass_for(klass)
16
+ hash[options] = nil_klass ? nil_query_object(klass) : klass_for(klass)
14
17
  end
15
18
  end
16
19
 
@@ -39,6 +42,10 @@ module HQ
39
42
  ::GraphQL::Types::Float
40
43
  when :boolean
41
44
  ::GraphQL::Types::Boolean
45
+ when :date
46
+ ::GraphQL::Types::ISO8601Date
47
+ when :datetime
48
+ ::GraphQL::Types::ISO8601DateTime
42
49
  else
43
50
  ::GraphQL::Types::String
44
51
  end
@@ -54,26 +61,20 @@ module HQ
54
61
  class << self
55
62
  private
56
63
 
57
- def nil_query_klass(klass_or_string)
58
- find_klass(klass_or_string, :nil_query_klass)
64
+ def nil_query_object(klass_or_string)
65
+ find_klass(klass_or_string, :nil_query_object)
59
66
  end
60
67
 
61
68
  def klass_for(klass_or_string)
62
- find_klass(klass_or_string, :query_klass)
69
+ find_klass(klass_or_string, :query_object)
63
70
  end
64
71
 
65
72
  def find_klass(klass_or_string, method)
66
73
  klass = klass_or_string.is_a?(String) ? klass_or_string.constantize : klass_or_string
67
- type = find_type(klass)
68
- type ||= find_type(klass.base_class)
69
- type ||= find_type(klass.superclass)
70
-
71
- raise(Error, Error::MISSING_TYPE_MSG % { klass: klass.name }) if !type
72
- type.send(method)
73
- end
74
+ resource = ::HQ::GraphQL.lookup_resource(klass)
74
75
 
75
- def find_type(klass)
76
- ::HQ::GraphQL.resource_lookup(klass) || ::HQ::GraphQL.types.detect { |t| t.model_klass == klass }
76
+ raise(Error, Error::MISSING_TYPE_MSG % { klass: klass.name }) if !resource
77
+ resource.send(method)
77
78
  end
78
79
  end
79
80
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module HQ
4
4
  module GraphQL
5
- VERSION = "2.0.10"
5
+ VERSION = "2.1.3"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hq-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.10
4
+ version: 2.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Jones
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-13 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -247,19 +247,25 @@ files:
247
247
  - lib/hq-graphql.rb
248
248
  - lib/hq/graphql.rb
249
249
  - lib/hq/graphql/active_record_extensions.rb
250
+ - lib/hq/graphql/association_loader.rb
250
251
  - lib/hq/graphql/comparator.rb
251
252
  - lib/hq/graphql/config.rb
252
253
  - lib/hq/graphql/engine.rb
253
254
  - lib/hq/graphql/enum.rb
255
+ - lib/hq/graphql/enum/sort_by.rb
256
+ - lib/hq/graphql/enum/sort_order.rb
254
257
  - lib/hq/graphql/field.rb
258
+ - lib/hq/graphql/field_extension/association_loader_extension.rb
259
+ - lib/hq/graphql/field_extension/paginated_arguments.rb
260
+ - lib/hq/graphql/field_extension/paginated_loader.rb
255
261
  - lib/hq/graphql/input_object.rb
256
262
  - lib/hq/graphql/inputs.rb
257
- - lib/hq/graphql/loaders.rb
258
- - lib/hq/graphql/loaders/association.rb
259
263
  - lib/hq/graphql/mutation.rb
260
264
  - lib/hq/graphql/object.rb
265
+ - lib/hq/graphql/object_association.rb
266
+ - lib/hq/graphql/paginated_association_loader.rb
261
267
  - lib/hq/graphql/resource.rb
262
- - lib/hq/graphql/resource/mutation.rb
268
+ - lib/hq/graphql/resource/auto_mutation.rb
263
269
  - lib/hq/graphql/root_mutation.rb
264
270
  - lib/hq/graphql/root_query.rb
265
271
  - lib/hq/graphql/scalars.rb
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "hq/graphql/loaders/association"
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module HQ
4
- module GraphQL
5
- module Loaders
6
- class Association < ::GraphQL::Batch::Loader
7
- def initialize(model, association_name)
8
- @model = model
9
- @association_name = association_name
10
- validate
11
- end
12
-
13
- def load(record)
14
- raise TypeError, "#{@model} loader can't load association for #{record.class}" unless record.is_a?(@model)
15
- return Promise.resolve(read_association(record)) if association_loaded?(record)
16
- super
17
- end
18
-
19
- # We want to load the associations on all records, even if they have the same id
20
- def cache_key(record)
21
- record.object_id
22
- end
23
-
24
- def perform(records)
25
- preload_association(records)
26
- records.each { |record| fulfill(record, read_association(record)) }
27
- end
28
-
29
- private
30
-
31
- def validate
32
- unless @model.reflect_on_association(@association_name)
33
- raise ArgumentError, "No association #{@association_name} on #{@model}"
34
- end
35
- end
36
-
37
- def preload_association(records)
38
- ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name)
39
- end
40
-
41
- def read_association(record)
42
- record.public_send(@association_name)
43
- end
44
-
45
- def association_loaded?(record)
46
- record.association(@association_name).loaded?
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module HQ
4
- module GraphQL
5
- module Resource
6
- module Mutation
7
- def self.build(model_name, action:, graphql_name:, require_primary_key: false, nil_klass: false, &block)
8
- Class.new(::HQ::GraphQL::Mutation) do
9
- graphql_name graphql_name
10
-
11
- define_method(:ready?) do |*args|
12
- super(*args) && ::HQ::GraphQL.authorized?(action, model_name, context)
13
- end
14
-
15
- lazy_load do
16
- field :errors, ::HQ::GraphQL::Types::Object, null: false
17
- field :resource, ::HQ::GraphQL::Types[model_name, nil_klass], null: true
18
- end
19
-
20
- instance_eval(&block)
21
-
22
- if require_primary_key
23
- lazy_load do
24
- klass = model_name.constantize
25
- primary_key = klass.primary_key
26
- argument primary_key, ::GraphQL::Types::ID, required: true
27
- end
28
- end
29
-
30
- def errors_from_resource(resource)
31
- resource.errors.to_h.deep_transform_keys { |k| k.to_s.camelize(:lower) }
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end