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.
- checksums.yaml +4 -4
- data/README.md +28 -0
- data/lib/hq-graphql.rb +0 -2
- data/lib/hq/graphql.rb +29 -20
- 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 -6
- data/lib/hq/graphql/config.rb +17 -11
- data/lib/hq/graphql/engine.rb +0 -1
- data/lib/hq/graphql/enum.rb +78 -0
- data/lib/hq/graphql/enum/sort_by.rb +8 -0
- data/lib/hq/graphql/enum/sort_order.rb +8 -0
- data/lib/hq/graphql/field.rb +26 -6
- data/lib/hq/graphql/input_object.rb +8 -7
- data/lib/hq/graphql/inputs.rb +4 -3
- data/lib/hq/graphql/mutation.rb +0 -1
- data/lib/hq/graphql/object.rb +15 -4
- data/lib/hq/graphql/paginated_association_loader.rb +138 -0
- data/lib/hq/graphql/resource.rb +47 -156
- data/lib/hq/graphql/resource/auto_mutation.rb +159 -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 +22 -0
- data/lib/hq/graphql/types.rb +19 -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 +9 -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
@@ -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.
|
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
|
data/lib/hq/graphql/scalars.rb
CHANGED
@@ -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
|
data/lib/hq/graphql/types.rb
CHANGED
@@ -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.
|
12
|
-
@
|
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
|
-
|
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
|
-
@
|
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.
|
58
|
-
|
59
|
-
|
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
|
-
|
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.0
|
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:
|
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/
|
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
|