hq-graphql 2.0.7 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -0
- data/lib/hq-graphql.rb +0 -2
- data/lib/hq/graphql.rb +28 -21
- data/lib/hq/graphql/active_record_extensions.rb +23 -27
- data/lib/hq/graphql/association_loader.rb +49 -0
- data/lib/hq/graphql/comparator.rb +1 -1
- data/lib/hq/graphql/config.rb +17 -11
- data/lib/hq/graphql/engine.rb +0 -1
- data/lib/hq/graphql/enum.rb +77 -0
- data/lib/hq/graphql/enum/sort_by.rb +10 -0
- data/lib/hq/graphql/enum/sort_order.rb +10 -0
- data/lib/hq/graphql/field.rb +12 -11
- data/lib/hq/graphql/field_extension/association_loader_extension.rb +15 -0
- data/lib/hq/graphql/field_extension/paginated_arguments.rb +22 -0
- data/lib/hq/graphql/field_extension/paginated_loader.rb +45 -0
- data/lib/hq/graphql/input_object.rb +12 -7
- data/lib/hq/graphql/inputs.rb +4 -3
- data/lib/hq/graphql/mutation.rb +0 -1
- data/lib/hq/graphql/object.rb +42 -11
- data/lib/hq/graphql/object_association.rb +50 -0
- data/lib/hq/graphql/paginated_association_loader.rb +158 -0
- data/lib/hq/graphql/resource.rb +47 -156
- data/lib/hq/graphql/resource/auto_mutation.rb +163 -0
- data/lib/hq/graphql/root_mutation.rb +1 -2
- data/lib/hq/graphql/root_query.rb +0 -1
- data/lib/hq/graphql/scalars.rb +0 -1
- data/lib/hq/graphql/schema.rb +1 -1
- data/lib/hq/graphql/types.rb +22 -8
- data/lib/hq/graphql/types/object.rb +7 -11
- data/lib/hq/graphql/types/uuid.rb +7 -14
- data/lib/hq/graphql/version.rb +1 -2
- metadata +12 -39
- data/lib/hq/graphql/loaders.rb +0 -4
- data/lib/hq/graphql/loaders/association.rb +0 -52
- data/lib/hq/graphql/resource/mutation.rb +0 -39
data/lib/hq/graphql/scalars.rb
CHANGED
data/lib/hq/graphql/schema.rb
CHANGED
data/lib/hq/graphql/types.rb
CHANGED
@@ -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.
|
12
|
-
@
|
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
|
-
|
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
|
-
@
|
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.
|
58
|
-
|
59
|
-
|
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
|
-
|
11
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
11
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
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
|
data/lib/hq/graphql/version.rb
CHANGED
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.
|
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:
|
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/
|
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
|
data/lib/hq/graphql/loaders.rb
DELETED
@@ -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
|