hq-graphql 2.0.6 → 2.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.
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HQ
4
+ module GraphQL
5
+ module Resource
6
+ module AutoMutation
7
+ def build_create
8
+ scoped_self = self
9
+
10
+ build_mutation(action: :create) do
11
+ define_method(:resolve) do |**args|
12
+ resource = scoped_self.new_record(context)
13
+ resource.assign_attributes(args[:attributes].format_nested_attributes)
14
+ if resource.save
15
+ {
16
+ resource: resource,
17
+ errors: {},
18
+ }
19
+ else
20
+ {
21
+ resource: nil,
22
+ errors: errors_from_resource(resource)
23
+ }
24
+ end
25
+ end
26
+
27
+ lazy_load do
28
+ argument :attributes, ::HQ::GraphQL::Inputs[scoped_self.model_name], required: true
29
+ end
30
+ end
31
+ end
32
+
33
+ def build_update
34
+ scoped_self = self
35
+
36
+ build_mutation(action: :update, require_primary_key: true) do
37
+ define_method(:resolve) do |**args|
38
+ resource = scoped_self.find_record(args, context)
39
+
40
+ if resource
41
+ resource.assign_attributes(args[:attributes].format_nested_attributes)
42
+ if resource.save
43
+ {
44
+ resource: resource,
45
+ errors: {},
46
+ }
47
+ else
48
+ {
49
+ resource: nil,
50
+ errors: errors_from_resource(resource)
51
+ }
52
+ end
53
+ else
54
+ {
55
+ resource: nil,
56
+ errors: { resource: "Unable to find #{self.class.graphql_name}" }
57
+ }
58
+ end
59
+ end
60
+
61
+ lazy_load do
62
+ argument :attributes, ::HQ::GraphQL::Inputs[scoped_self.model_name], required: true
63
+ end
64
+ end
65
+ end
66
+
67
+ def build_copy
68
+ scoped_self = self
69
+
70
+ build_mutation(action: :copy, require_primary_key: true, nil_klass: true) do
71
+ define_method(:resolve) do |**args|
72
+ resource = scoped_self.find_record(args, context)
73
+
74
+ if resource
75
+ copy = resource.copy
76
+ if copy.save
77
+ {
78
+ resource: copy,
79
+ errors: {},
80
+ }
81
+ else
82
+ {
83
+ resource: copy,
84
+ errors: errors_from_resource(copy)
85
+ }
86
+ end
87
+ else
88
+ {
89
+ resource: nil,
90
+ errors: { resource: "Unable to find #{self.class.graphql_name}" }
91
+ }
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def build_destroy
98
+ scoped_self = self
99
+
100
+ build_mutation(action: :destroy, require_primary_key: true) do
101
+ define_method(:resolve) do |**attrs|
102
+ resource = scoped_self.find_record(attrs, context)
103
+
104
+ if resource
105
+ if resource.destroy
106
+ {
107
+ resource: resource,
108
+ errors: {},
109
+ }
110
+ else
111
+ {
112
+ resource: nil,
113
+ errors: errors_from_resource(resource)
114
+ }
115
+ end
116
+ else
117
+ {
118
+ resource: nil,
119
+ errors: { resource: "Unable to find #{self.class.graphql_name}" }
120
+ }
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ def build_mutation(action:, require_primary_key: false, nil_klass: false, &block)
127
+ gql_name = "#{graphql_name}#{action.to_s.titleize}"
128
+ scoped_model_name = model_name
129
+ Class.new(::HQ::GraphQL::Mutation) do
130
+ graphql_name gql_name
131
+
132
+ define_method(:ready?) do |*args|
133
+ super(*args) && ::HQ::GraphQL.authorized?(action, scoped_model_name, context)
134
+ end
135
+
136
+ lazy_load do
137
+ field :errors, ::HQ::GraphQL::Types::Object, null: false
138
+ field :resource, ::HQ::GraphQL::Types[scoped_model_name, nil_klass], null: true
139
+ end
140
+
141
+ instance_eval(&block)
142
+
143
+ if require_primary_key
144
+ lazy_load do
145
+ klass = scoped_model_name.constantize
146
+ primary_key = klass.primary_key
147
+ argument primary_key, ::GraphQL::Types::ID, required: true
148
+ end
149
+ end
150
+
151
+ def errors_from_resource(resource)
152
+ resource.errors.to_h.deep_transform_keys { |k| k.to_s.camelize(:lower) }
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -1,4 +1,3 @@
1
- # typed: true
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module HQ
@@ -8,7 +7,7 @@ module HQ
8
7
  super
9
8
  base.class_eval do
10
9
  lazy_load do
11
- ::HQ::GraphQL.types.each do |type|
10
+ ::HQ::GraphQL.resources.each do |type|
12
11
  type.mutation_klasses.each do |mutation_name, klass|
13
12
  field mutation_name, mutation: klass
14
13
  end
@@ -1,4 +1,3 @@
1
- # typed: true
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module HQ
@@ -1,4 +1,3 @@
1
- # typed: strict
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require "hq/graphql/types/object"
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HQ
4
+ module GraphQL
5
+ class Schema < ::GraphQL::Schema
6
+ class << self
7
+ def dump_directory(directory = Rails.root.join("app/graphql"))
8
+ @dump_directory ||= directory
9
+ end
10
+
11
+ def dump_filename(filename = "#{self.name.underscore}.graphql")
12
+ @dump_filename ||= filename
13
+ end
14
+
15
+ def dump
16
+ ::FileUtils.mkdir_p(dump_directory)
17
+ ::File.open(::File.join(dump_directory, dump_filename), "w") { |file| file.write(self.to_definition) }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,3 @@
1
- # typed: true
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module HQ
@@ -8,12 +7,23 @@ module HQ
8
7
  MISSING_TYPE_MSG = "The GraphQL type for `%{klass}` is missing."
9
8
  end
10
9
 
11
- def self.[](key, *args)
12
- @types ||= Hash.new do |hash, options|
10
+ def self.registry
11
+ @registry ||= Hash.new do |hash, options|
13
12
  klass, nil_klass = Array(options)
14
13
  hash[klass] = nil_klass ? nil_query_klass(klass) : klass_for(klass)
15
14
  end
16
- @types[[key, *args]]
15
+ end
16
+
17
+ def self.register(k, v)
18
+ self[k] = v
19
+ end
20
+
21
+ def self.[]=(key, is_nil = false, value)
22
+ registry[[key, is_nil]] = value
23
+ end
24
+
25
+ def self.[](key, is_nil = false)
26
+ registry[[key, is_nil]]
17
27
  end
18
28
 
19
29
  def self.type_from_column(column)
@@ -38,7 +48,7 @@ module HQ
38
48
 
39
49
  # Only being used in testing
40
50
  def self.reset!
41
- @types = nil
51
+ @registry = nil
42
52
  end
43
53
 
44
54
  class << self
@@ -54,9 +64,10 @@ module HQ
54
64
 
55
65
  def find_klass(klass_or_string, method)
56
66
  klass = klass_or_string.is_a?(String) ? klass_or_string.constantize : klass_or_string
57
- ::HQ::GraphQL.types.detect { |t| t.model_klass == klass }&.send(method) ||
58
- ::HQ::GraphQL.types.detect { |t| t.model_klass == klass.base_class }&.send(method) ||
59
- raise(Error, Error::MISSING_TYPE_MSG % { klass: klass.name })
67
+ resource = ::HQ::GraphQL.lookup_resource(klass)
68
+
69
+ raise(Error, Error::MISSING_TYPE_MSG % { klass: klass.name }) if !resource
70
+ resource.send(method)
60
71
  end
61
72
  end
62
73
  end
@@ -1,4 +1,3 @@
1
- # typed: true
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module HQ
@@ -7,17 +6,15 @@ module HQ
7
6
  class Object < ::GraphQL::Schema::Scalar
8
7
  description "Object"
9
8
 
10
- class << self
11
- extend T::Sig
12
-
13
- def coerce_input(value, _context)
14
- validate_and_return_object(value)
15
- end
9
+ def self.coerce_input(value, _context)
10
+ validate_and_return_object(value)
11
+ end
16
12
 
17
- def coerce_result(value, _context)
18
- validate_and_return_object(value)
19
- end
13
+ def self.coerce_result(value, _context)
14
+ validate_and_return_object(value)
15
+ end
20
16
 
17
+ class << self
21
18
  private
22
19
 
23
20
  def validate_and_return_object(value)
@@ -28,7 +25,6 @@ module HQ
28
25
  end
29
26
  end
30
27
 
31
- sig { params(value: T.untyped).returns(T::Boolean) }
32
28
  def validate_object(value)
33
29
  value.is_a?(Hash)
34
30
  end
@@ -1,4 +1,3 @@
1
- # typed: strict
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module HQ
@@ -7,22 +6,17 @@ module HQ
7
6
  class UUID < ::GraphQL::Schema::Scalar
8
7
  description "UUID"
9
8
 
10
- class << self
11
- extend T::Sig
12
-
13
- sig { params(value: T.untyped, _context: T.untyped).returns(String) }
14
- def coerce_input(value, _context)
15
- validate_and_return_uuid(value)
16
- end
9
+ def self.coerce_input(value, _context)
10
+ validate_and_return_uuid(value)
11
+ end
17
12
 
18
- sig { params(value: T.untyped, _context: T.untyped).returns(String) }
19
- def coerce_result(value, _context)
20
- validate_and_return_uuid(value)
21
- end
13
+ def self.coerce_result(value, _context)
14
+ validate_and_return_uuid(value)
15
+ end
22
16
 
17
+ class << self
23
18
  private
24
19
 
25
- sig { params(value: T.untyped).returns(String) }
26
20
  def validate_and_return_uuid(value)
27
21
  if validate_uuid(value)
28
22
  value
@@ -31,7 +25,6 @@ module HQ
31
25
  end
32
26
  end
33
27
 
34
- sig { params(value: T.untyped).returns(T::Boolean) }
35
28
  def validate_uuid(value)
36
29
  !!value.to_s.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
37
30
  end
@@ -1,8 +1,7 @@
1
- # typed: strong
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module HQ
5
4
  module GraphQL
6
- VERSION = "2.0.6"
5
+ VERSION = "2.1.0"
7
6
  end
8
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.6
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Jones
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-25 00:00:00.000000000 Z
11
+ date: 2020-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -29,9 +29,6 @@ dependencies:
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.0'
34
- - - ">="
35
32
  - !ruby/object:Gem::Version
36
33
  version: 1.9.6
37
34
  type: :runtime
@@ -39,9 +36,6 @@ dependencies:
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - "~>"
42
- - !ruby/object:Gem::Version
43
- version: '1.0'
44
- - - ">="
45
39
  - !ruby/object:Gem::Version
46
40
  version: 1.9.6
47
41
  - !ruby/object:Gem::Dependency
@@ -86,20 +80,6 @@ dependencies:
86
80
  - - "~>"
87
81
  - !ruby/object:Gem::Version
88
82
  version: '1.1'
89
- - !ruby/object:Gem::Dependency
90
- name: sorbet-runtime
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: '0'
96
- type: :runtime
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- version: '0'
103
83
  - !ruby/object:Gem::Dependency
104
84
  name: sprockets
105
85
  requirement: !ruby/object:Gem::Requirement
@@ -254,20 +234,6 @@ dependencies:
254
234
  - - "~>"
255
235
  - !ruby/object:Gem::Version
256
236
  version: '2.3'
257
- - !ruby/object:Gem::Dependency
258
- name: sorbet
259
- requirement: !ruby/object:Gem::Requirement
260
- requirements:
261
- - - ">="
262
- - !ruby/object:Gem::Version
263
- version: '0'
264
- type: :development
265
- prerelease: false
266
- version_requirements: !ruby/object:Gem::Requirement
267
- requirements:
268
- - - ">="
269
- - !ruby/object:Gem::Version
270
- version: '0'
271
237
  description: OneHQ GraphQL Library
272
238
  email:
273
239
  - dpjones09@gmail.com
@@ -281,21 +247,25 @@ files:
281
247
  - lib/hq-graphql.rb
282
248
  - lib/hq/graphql.rb
283
249
  - lib/hq/graphql/active_record_extensions.rb
250
+ - lib/hq/graphql/association_loader.rb
284
251
  - lib/hq/graphql/comparator.rb
285
252
  - lib/hq/graphql/config.rb
286
253
  - lib/hq/graphql/engine.rb
254
+ - lib/hq/graphql/enum.rb
255
+ - lib/hq/graphql/enum/sort_by.rb
256
+ - lib/hq/graphql/enum/sort_order.rb
287
257
  - lib/hq/graphql/field.rb
288
258
  - lib/hq/graphql/input_object.rb
289
259
  - lib/hq/graphql/inputs.rb
290
- - lib/hq/graphql/loaders.rb
291
- - lib/hq/graphql/loaders/association.rb
292
260
  - lib/hq/graphql/mutation.rb
293
261
  - lib/hq/graphql/object.rb
262
+ - lib/hq/graphql/paginated_association_loader.rb
294
263
  - lib/hq/graphql/resource.rb
295
- - lib/hq/graphql/resource/mutation.rb
264
+ - lib/hq/graphql/resource/auto_mutation.rb
296
265
  - lib/hq/graphql/root_mutation.rb
297
266
  - lib/hq/graphql/root_query.rb
298
267
  - lib/hq/graphql/scalars.rb
268
+ - lib/hq/graphql/schema.rb
299
269
  - lib/hq/graphql/types.rb
300
270
  - lib/hq/graphql/types/object.rb
301
271
  - lib/hq/graphql/types/uuid.rb