hq-graphql 2.0.7 → 2.1.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -0
  3. data/lib/hq-graphql.rb +0 -2
  4. data/lib/hq/graphql.rb +28 -21
  5. data/lib/hq/graphql/active_record_extensions.rb +23 -27
  6. data/lib/hq/graphql/association_loader.rb +49 -0
  7. data/lib/hq/graphql/comparator.rb +1 -1
  8. data/lib/hq/graphql/config.rb +17 -11
  9. data/lib/hq/graphql/engine.rb +0 -1
  10. data/lib/hq/graphql/enum.rb +77 -0
  11. data/lib/hq/graphql/enum/sort_by.rb +10 -0
  12. data/lib/hq/graphql/enum/sort_order.rb +10 -0
  13. data/lib/hq/graphql/field.rb +12 -11
  14. data/lib/hq/graphql/field_extension/association_loader_extension.rb +15 -0
  15. data/lib/hq/graphql/field_extension/paginated_arguments.rb +22 -0
  16. data/lib/hq/graphql/field_extension/paginated_loader.rb +45 -0
  17. data/lib/hq/graphql/input_object.rb +12 -7
  18. data/lib/hq/graphql/inputs.rb +4 -3
  19. data/lib/hq/graphql/mutation.rb +0 -1
  20. data/lib/hq/graphql/object.rb +42 -11
  21. data/lib/hq/graphql/object_association.rb +50 -0
  22. data/lib/hq/graphql/paginated_association_loader.rb +158 -0
  23. data/lib/hq/graphql/resource.rb +47 -156
  24. data/lib/hq/graphql/resource/auto_mutation.rb +163 -0
  25. data/lib/hq/graphql/root_mutation.rb +1 -2
  26. data/lib/hq/graphql/root_query.rb +0 -1
  27. data/lib/hq/graphql/scalars.rb +0 -1
  28. data/lib/hq/graphql/schema.rb +1 -1
  29. data/lib/hq/graphql/types.rb +22 -8
  30. data/lib/hq/graphql/types/object.rb +7 -11
  31. data/lib/hq/graphql/types/uuid.rb +7 -14
  32. data/lib/hq/graphql/version.rb +1 -2
  33. metadata +12 -39
  34. data/lib/hq/graphql/loaders.rb +0 -4
  35. data/lib/hq/graphql/loaders/association.rb +0 -52
  36. data/lib/hq/graphql/resource/mutation.rb +0 -39
@@ -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"
@@ -4,7 +4,7 @@ module HQ
4
4
  module GraphQL
5
5
  class Schema < ::GraphQL::Schema
6
6
  class << self
7
- def dump_directory(directory = Rails.root.join("app", "graphql"))
7
+ def dump_directory(directory = Rails.root.join("app/graphql"))
8
8
  @dump_directory ||= directory
9
9
  end
10
10
 
@@ -1,6 +1,8 @@
1
- # typed: true
2
1
  # frozen_string_literal: true
3
2
 
3
+ require "hq/graphql/types/object"
4
+ require "hq/graphql/types/uuid"
5
+
4
6
  module HQ
5
7
  module GraphQL
6
8
  module Types
@@ -8,12 +10,23 @@ module HQ
8
10
  MISSING_TYPE_MSG = "The GraphQL type for `%{klass}` is missing."
9
11
  end
10
12
 
11
- def self.[](key, *args)
12
- @types ||= Hash.new do |hash, options|
13
+ def self.registry
14
+ @registry ||= Hash.new do |hash, options|
13
15
  klass, nil_klass = Array(options)
14
16
  hash[klass] = nil_klass ? nil_query_klass(klass) : klass_for(klass)
15
17
  end
16
- @types[[key, *args]]
18
+ end
19
+
20
+ def self.register(k, v)
21
+ self[k] = v
22
+ end
23
+
24
+ def self.[]=(key, is_nil = false, value)
25
+ registry[[key, is_nil]] = value
26
+ end
27
+
28
+ def self.[](key, is_nil = false)
29
+ registry[[key, is_nil]]
17
30
  end
18
31
 
19
32
  def self.type_from_column(column)
@@ -38,7 +51,7 @@ module HQ
38
51
 
39
52
  # Only being used in testing
40
53
  def self.reset!
41
- @types = nil
54
+ @registry = nil
42
55
  end
43
56
 
44
57
  class << self
@@ -54,9 +67,10 @@ module HQ
54
67
 
55
68
  def find_klass(klass_or_string, method)
56
69
  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 })
70
+ resource = ::HQ::GraphQL.lookup_resource(klass)
71
+
72
+ raise(Error, Error::MISSING_TYPE_MSG % { klass: klass.name }) if !resource
73
+ resource.send(method)
60
74
  end
61
75
  end
62
76
  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.7"
5
+ VERSION = "2.1.1"
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.7
4
+ version: 2.1.1
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-26 00:00:00.000000000 Z
11
+ date: 2020-06-22 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,18 +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
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
288
261
  - lib/hq/graphql/input_object.rb
289
262
  - lib/hq/graphql/inputs.rb
290
- - lib/hq/graphql/loaders.rb
291
- - lib/hq/graphql/loaders/association.rb
292
263
  - lib/hq/graphql/mutation.rb
293
264
  - lib/hq/graphql/object.rb
265
+ - lib/hq/graphql/object_association.rb
266
+ - lib/hq/graphql/paginated_association_loader.rb
294
267
  - lib/hq/graphql/resource.rb
295
- - lib/hq/graphql/resource/mutation.rb
268
+ - lib/hq/graphql/resource/auto_mutation.rb
296
269
  - lib/hq/graphql/root_mutation.rb
297
270
  - lib/hq/graphql/root_query.rb
298
271
  - lib/hq/graphql/scalars.rb
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # typed: strict
4
- require "hq/graphql/loaders/association"
@@ -1,52 +0,0 @@
1
- # typed: false
2
- # frozen_string_literal: true
3
-
4
- module HQ
5
- module GraphQL
6
- module Loaders
7
- class Association < ::GraphQL::Batch::Loader
8
- def initialize(model, association_name)
9
- @model = model
10
- @association_name = association_name
11
- validate
12
- end
13
-
14
- def load(record)
15
- raise TypeError, "#{@model} loader can't load association for #{record.class}" unless record.is_a?(@model)
16
- return Promise.resolve(read_association(record)) if association_loaded?(record)
17
- super
18
- end
19
-
20
- # We want to load the associations on all records, even if they have the same id
21
- def cache_key(record)
22
- record.object_id
23
- end
24
-
25
- def perform(records)
26
- preload_association(records)
27
- records.each { |record| fulfill(record, read_association(record)) }
28
- end
29
-
30
- private
31
-
32
- def validate
33
- unless @model.reflect_on_association(@association_name)
34
- raise ArgumentError, "No association #{@association_name} on #{@model}"
35
- end
36
- end
37
-
38
- def preload_association(records)
39
- ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name)
40
- end
41
-
42
- def read_association(record)
43
- record.public_send(@association_name)
44
- end
45
-
46
- def association_loaded?(record)
47
- record.association(@association_name).loaded?
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,39 +0,0 @@
1
- # typed: false
2
- # frozen_string_literal: true
3
-
4
- module HQ
5
- module GraphQL
6
- module Resource
7
- module Mutation
8
- def self.build(model_name, action:, graphql_name:, require_primary_key: false, nil_klass: false, &block)
9
- Class.new(::HQ::GraphQL::Mutation) do
10
- graphql_name graphql_name
11
-
12
- define_method(:ready?) do |*args|
13
- super(*args) && ::HQ::GraphQL.authorized?(action, model_name, context)
14
- end
15
-
16
- lazy_load do
17
- field :errors, ::HQ::GraphQL::Types::Object, null: false
18
- field :resource, ::HQ::GraphQL::Types[model_name, nil_klass], null: true
19
- end
20
-
21
- instance_eval(&block)
22
-
23
- if require_primary_key
24
- lazy_load do
25
- klass = model_name.constantize
26
- primary_key = klass.primary_key
27
- argument primary_key, ::GraphQL::Types::ID, required: true
28
- end
29
- end
30
-
31
- def errors_from_resource(resource)
32
- resource.errors.to_h.deep_transform_keys { |k| k.to_s.camelize(:lower) }
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end