hq-graphql 2.0.7 → 2.0.9
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/active_record_extensions.rb +23 -27
- data/lib/hq/graphql/comparator.rb +1 -1
- data/lib/hq/graphql/config.rb +8 -11
- data/lib/hq/graphql/engine.rb +0 -1
- data/lib/hq/graphql/enum.rb +75 -0
- data/lib/hq/graphql/field.rb +0 -1
- data/lib/hq/graphql/input_object.rb +8 -7
- data/lib/hq/graphql/inputs.rb +8 -3
- data/lib/hq/graphql/loaders/association.rb +0 -1
- data/lib/hq/graphql/loaders.rb +0 -1
- data/lib/hq/graphql/mutation.rb +0 -1
- data/lib/hq/graphql/object.rb +2 -2
- data/lib/hq/graphql/resource/mutation.rb +0 -1
- data/lib/hq/graphql/resource.rb +1 -5
- data/lib/hq/graphql/root_mutation.rb +0 -1
- 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/object.rb +7 -11
- data/lib/hq/graphql/types/uuid.rb +7 -14
- data/lib/hq/graphql/types.rb +25 -8
- data/lib/hq/graphql/version.rb +1 -2
- data/lib/hq/graphql.rb +13 -16
- data/lib/hq-graphql.rb +0 -2
- metadata +3 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf94ca5592ce063239e928dbfb76d339c44762c3c89efe709cbbee157228a1d5
|
4
|
+
data.tar.gz: 8a5b48518fd85b87917d81dc10b75be7031552b010216ff956e3d7e9fefada0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a742fb51ad7ac2c4fa2f44c02b144a97e7e87fb9bb93c58035a23420c89550bfc895f376d372b71ee1445fdf8db91bf38e16eae8d7cea3c91dfeda9e5a2f69d
|
7
|
+
data.tar.gz: d17914db4d42d8b480917d3b720220cbdcad9d5d5a88f47d1e4b7c0b1f1d8db69138560e5838be40047f42a003bb82d56c07ede142da433b541048fba1d5dc56
|
data/README.md
CHANGED
@@ -78,6 +78,34 @@ class AdvisorResource
|
|
78
78
|
end
|
79
79
|
```
|
80
80
|
|
81
|
+
### Enums
|
82
|
+
Auto generate enums from the database using ActiveRecord
|
83
|
+
This comes in handy when we have constants that we want represented as enums.
|
84
|
+
|
85
|
+
#### Example
|
86
|
+
Let's assume we're saving data into a user types table
|
87
|
+
```postgresl
|
88
|
+
# select * from user_types;
|
89
|
+
id | name
|
90
|
+
--- +-------------
|
91
|
+
1 | Admin
|
92
|
+
2 | Support User
|
93
|
+
(2 rows)
|
94
|
+
```
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
class Enums::UserType < ::HQ::GraphQL::Enum
|
98
|
+
with_model
|
99
|
+
end
|
100
|
+
```
|
101
|
+
This class automatically uses the UserType ActiveRecord model to generate an enum:
|
102
|
+
```graphql
|
103
|
+
enum UserType {
|
104
|
+
Admin
|
105
|
+
SupportUser
|
106
|
+
}
|
107
|
+
```
|
108
|
+
|
81
109
|
### Root Mutations
|
82
110
|
Add mutations to your schema
|
83
111
|
|
@@ -1,35 +1,31 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module HQ
|
5
4
|
module GraphQL
|
6
5
|
module ActiveRecordExtensions
|
7
|
-
extend T::Sig
|
8
|
-
extend T::Helpers
|
9
|
-
|
10
6
|
class Error < StandardError
|
11
7
|
MISSING_MODEL_MSG = "Your GraphQL object must be connected to a model: `::HQ::GraphQL::Object.with_model 'User'`"
|
12
8
|
MISSING_ATTR_MSG = "Can't find attr %{model}.%{attr}'`"
|
13
9
|
MISSING_ASSOC_MSG = "Can't find association %{model}.%{assoc}'`"
|
14
10
|
end
|
15
11
|
|
16
|
-
|
17
|
-
extend
|
18
|
-
|
12
|
+
def self.included(klass)
|
13
|
+
klass.extend(ClassMethods)
|
14
|
+
end
|
19
15
|
|
16
|
+
module ClassMethods
|
20
17
|
attr_accessor :model_name,
|
21
18
|
:authorize_action,
|
22
19
|
:auto_load_attributes,
|
23
|
-
:auto_load_associations
|
20
|
+
:auto_load_associations,
|
21
|
+
:auto_load_enums
|
24
22
|
|
25
|
-
sig { params(block: T.nilable(T.proc.void)).returns(T::Array[T.proc.void]) }
|
26
23
|
def lazy_load(&block)
|
27
24
|
@lazy_load ||= []
|
28
25
|
@lazy_load << block if block
|
29
26
|
@lazy_load
|
30
27
|
end
|
31
28
|
|
32
|
-
sig { void }
|
33
29
|
def lazy_load!
|
34
30
|
lazy_load.map(&:call)
|
35
31
|
@lazy_load = []
|
@@ -50,12 +46,19 @@ module HQ
|
|
50
46
|
end
|
51
47
|
|
52
48
|
def model_associations
|
53
|
-
model_associations =
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
model_associations = []
|
50
|
+
enums = model_klass.reflect_on_all_associations.select { |a| is_enum?(a) }
|
51
|
+
associatons = model_klass.reflect_on_all_associations - enums
|
52
|
+
|
53
|
+
if auto_load_enums
|
54
|
+
model_associations.concat(enums)
|
55
|
+
end
|
56
|
+
|
57
|
+
if auto_load_associations
|
58
|
+
model_associations.concat(associatons)
|
59
|
+
end
|
60
|
+
|
61
|
+
model_associations.concat(added_associations.map { |association| association_from_model(association) }).uniq
|
59
62
|
|
60
63
|
# validate removed_associations exist
|
61
64
|
removed_associations.each { |association| association_from_model(association) }
|
@@ -65,7 +68,6 @@ module HQ
|
|
65
68
|
|
66
69
|
private
|
67
70
|
|
68
|
-
sig { params(attrs: T.any(String, Symbol)).void }
|
69
71
|
def add_attributes(*attrs)
|
70
72
|
validate_model!
|
71
73
|
added_attributes.concat attrs.map(&:to_sym)
|
@@ -74,7 +76,6 @@ module HQ
|
|
74
76
|
alias_method :add_attrs, :add_attributes
|
75
77
|
alias_method :add_attr, :add_attributes
|
76
78
|
|
77
|
-
sig { params(attrs: T.any(String, Symbol)).void }
|
78
79
|
def remove_attributes(*attrs)
|
79
80
|
validate_model!
|
80
81
|
removed_attributes.concat attrs.map(&:to_sym)
|
@@ -83,14 +84,12 @@ module HQ
|
|
83
84
|
alias_method :remove_attrs, :remove_attributes
|
84
85
|
alias_method :remove_attr, :remove_attributes
|
85
86
|
|
86
|
-
sig { params(associations: T.any(String, Symbol)).void }
|
87
87
|
def add_associations(*associations)
|
88
88
|
validate_model!
|
89
89
|
added_associations.concat associations.map(&:to_sym)
|
90
90
|
end
|
91
91
|
alias_method :add_association, :add_associations
|
92
92
|
|
93
|
-
sig { params(associations: T.any(String, Symbol)).void }
|
94
93
|
def remove_associations(*associations)
|
95
94
|
validate_model!
|
96
95
|
removed_associations.concat associations.map(&:to_sym)
|
@@ -101,7 +100,6 @@ module HQ
|
|
101
100
|
@model_klass ||= model_name.constantize
|
102
101
|
end
|
103
102
|
|
104
|
-
sig { params(attr: Symbol).returns(T.untyped) }
|
105
103
|
def column_from_model(attr)
|
106
104
|
model_klass.columns_hash[attr.to_s] || raise(Error, Error::MISSING_ATTR_MSG % { model: model_name, attr: attr })
|
107
105
|
end
|
@@ -110,34 +108,32 @@ module HQ
|
|
110
108
|
model_klass.reflect_on_association(association) || raise(Error, Error::MISSING_ASSOC_MSG % { model: model_name, assoc: association })
|
111
109
|
end
|
112
110
|
|
113
|
-
sig { returns(T::Array[Symbol]) }
|
114
111
|
def added_attributes
|
115
112
|
@added_attributes ||= []
|
116
113
|
end
|
117
114
|
|
118
|
-
sig { returns(T::Array[Symbol]) }
|
119
115
|
def removed_attributes
|
120
116
|
@removed_attributes ||= []
|
121
117
|
end
|
122
118
|
|
123
|
-
sig { returns(T::Array[Symbol]) }
|
124
119
|
def added_associations
|
125
120
|
@added_associations ||= []
|
126
121
|
end
|
127
122
|
|
128
|
-
sig { returns(T::Array[Symbol]) }
|
129
123
|
def removed_associations
|
130
124
|
@removed_associations ||= []
|
131
125
|
end
|
132
126
|
|
133
|
-
|
127
|
+
def is_enum?(association)
|
128
|
+
::HQ::GraphQL.enums.include?(association.klass)
|
129
|
+
end
|
130
|
+
|
134
131
|
def validate_model!
|
135
132
|
lazy_load do
|
136
133
|
model_name || raise(Error, Error::MISSING_MODEL_MSG)
|
137
134
|
end
|
138
135
|
end
|
139
136
|
end
|
140
|
-
mixes_in_class_methods(ClassMethods)
|
141
137
|
end
|
142
138
|
end
|
143
139
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
require "graphql/schema_comparator"
|
@@ -30,6 +29,7 @@ module HQ
|
|
30
29
|
if level >= CRITICALITY[:non_breaking]
|
31
30
|
changes[:non_breaking] = result.non_breaking_changes
|
32
31
|
end
|
32
|
+
return nil unless changes.values.flatten.any?
|
33
33
|
|
34
34
|
changes
|
35
35
|
end
|
data/lib/hq/graphql/config.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# typed: strict
|
4
|
-
|
5
3
|
module HQ
|
6
4
|
module GraphQL
|
7
|
-
class Config <
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
prop :default_scope, DefaultScopeProc, default: ->(scope, _context) { scope }
|
5
|
+
class Config < Struct.new(:authorize, :authorize_field, :default_scope, :resource_lookup, keyword_init: true)
|
6
|
+
def initialize(
|
7
|
+
default_scope: ->(scope, _context) { scope },
|
8
|
+
resource_lookup: ->(klass) { "::Resources::#{klass}".safe_constantize },
|
9
|
+
**options
|
10
|
+
)
|
11
|
+
super
|
12
|
+
end
|
16
13
|
end
|
17
14
|
end
|
18
15
|
end
|
data/lib/hq/graphql/engine.rb
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HQ::GraphQL
|
4
|
+
class Enum < ::GraphQL::Schema::Enum
|
5
|
+
## Auto generate enums from the database using ActiveRecord
|
6
|
+
# This comes in handy when we have constants that we want represented as enums.
|
7
|
+
#
|
8
|
+
# == Example
|
9
|
+
# Let's assume we're saving data into a user types table
|
10
|
+
# # select * from user_types;
|
11
|
+
# id | name
|
12
|
+
# --- +-------------
|
13
|
+
# 1 | Admin
|
14
|
+
# 2 | Support User
|
15
|
+
# (2 rows)
|
16
|
+
#
|
17
|
+
# ```ruby
|
18
|
+
# class Enums::UserType < ::HQ::GraphQL::Enum
|
19
|
+
# with_model
|
20
|
+
# end
|
21
|
+
# ```
|
22
|
+
#
|
23
|
+
# Creates the following enum:
|
24
|
+
# ```graphql
|
25
|
+
# enum UserType {
|
26
|
+
# Admin
|
27
|
+
# SupportUser
|
28
|
+
# }
|
29
|
+
# ```
|
30
|
+
def self.with_model(
|
31
|
+
klass = default_model_name.safe_constantize,
|
32
|
+
prefix: nil,
|
33
|
+
register: true,
|
34
|
+
scope: nil,
|
35
|
+
value_method: :name
|
36
|
+
)
|
37
|
+
raise ArgumentError.new(<<~ERROR) if !klass
|
38
|
+
`::HQ::GraphQL::Enum.with_model {...}' had trouble automatically inferring the class name.
|
39
|
+
Avoid this by manually passing in the class name: `::HQ::GraphQL::Enum.with_model(#{default_model_name}) {...}`
|
40
|
+
ERROR
|
41
|
+
|
42
|
+
if register
|
43
|
+
::HQ::GraphQL.enums << klass
|
44
|
+
::HQ::GraphQL::Types.register(klass, self)
|
45
|
+
end
|
46
|
+
|
47
|
+
lazy_load do
|
48
|
+
records = scope ? klass.instance_exec(&scope) : klass.all
|
49
|
+
records.each do |record|
|
50
|
+
value "#{prefix}#{record.send(value_method).delete(" ")}", value: record
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.lazy_load(&block)
|
56
|
+
@lazy_load ||= []
|
57
|
+
@lazy_load << block if block
|
58
|
+
@lazy_load
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.lazy_load!
|
62
|
+
lazy_load.map(&:call)
|
63
|
+
@lazy_load = []
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.to_graphql
|
67
|
+
lazy_load!
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.default_model_name
|
72
|
+
to_s.sub(/^((::)?\w+)::/, "")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/hq/graphql/field.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module HQ
|
5
4
|
module GraphQL
|
6
5
|
class InputObject < ::GraphQL::Schema::InputObject
|
7
|
-
extend T::Sig
|
8
6
|
include Scalars
|
9
7
|
include ::HQ::GraphQL::ActiveRecordExtensions
|
10
8
|
|
@@ -30,11 +28,11 @@ module HQ
|
|
30
28
|
end
|
31
29
|
|
32
30
|
#### Class Methods ####
|
33
|
-
|
34
|
-
def self.with_model(model_name, attributes: true, associations: false)
|
31
|
+
def self.with_model(model_name, attributes: true, associations: false, enums: true)
|
35
32
|
self.model_name = model_name
|
36
33
|
self.auto_load_attributes = attributes
|
37
34
|
self.auto_load_associations = associations
|
35
|
+
self.auto_load_enums = enums
|
38
36
|
|
39
37
|
lazy_load do
|
40
38
|
model_columns.each do |column|
|
@@ -62,16 +60,19 @@ module HQ
|
|
62
60
|
private
|
63
61
|
|
64
62
|
def argument_from_association(association)
|
65
|
-
|
63
|
+
is_enum = is_enum?(association)
|
64
|
+
input_or_type = is_enum ? ::HQ::GraphQL::Types[association.klass] : ::HQ::GraphQL::Inputs[association.klass]
|
66
65
|
name = association.name
|
67
66
|
|
68
67
|
case association.macro
|
69
68
|
when :has_many
|
70
|
-
argument name, [
|
69
|
+
argument name, [input_or_type], required: false
|
71
70
|
else
|
72
|
-
argument name,
|
71
|
+
argument name, input_or_type, required: false
|
73
72
|
end
|
74
73
|
|
74
|
+
return if is_enum
|
75
|
+
|
75
76
|
if !model_klass.nested_attributes_options.key?(name.to_sym)
|
76
77
|
model_klass.accepts_nested_attributes_for name, allow_destroy: true
|
77
78
|
end
|
data/lib/hq/graphql/inputs.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module HQ
|
@@ -25,8 +24,14 @@ module HQ
|
|
25
24
|
|
26
25
|
def klass_for(klass_or_string)
|
27
26
|
klass = klass_or_string.is_a?(String) ? klass_or_string.constantize : klass_or_string
|
28
|
-
|
29
|
-
|
27
|
+
type = find_type(klass)
|
28
|
+
|
29
|
+
raise(Error, Error::MISSING_TYPE_MSG % { klass: klass.name }) if !type
|
30
|
+
type.input_klass
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_type(klass)
|
34
|
+
::HQ::GraphQL.resource_lookup(klass) || ::HQ::GraphQL.types.detect { |t| t.model_klass == klass }
|
30
35
|
end
|
31
36
|
end
|
32
37
|
end
|
data/lib/hq/graphql/loaders.rb
CHANGED
data/lib/hq/graphql/mutation.rb
CHANGED
data/lib/hq/graphql/object.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module HQ
|
@@ -17,10 +16,11 @@ module HQ
|
|
17
16
|
super && ::HQ::GraphQL.authorized?(authorized_action, object, context)
|
18
17
|
end
|
19
18
|
|
20
|
-
def self.with_model(model_name, attributes: true, associations: true, auto_nil: true)
|
19
|
+
def self.with_model(model_name, attributes: true, associations: true, auto_nil: true, enums: true)
|
21
20
|
self.model_name = model_name
|
22
21
|
self.auto_load_attributes = attributes
|
23
22
|
self.auto_load_associations = associations
|
23
|
+
self.auto_load_enums = enums
|
24
24
|
|
25
25
|
lazy_load do
|
26
26
|
model_columns.each do |column|
|
data/lib/hq/graphql/resource.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: false
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
require "hq/graphql/resource/mutation"
|
@@ -6,13 +5,12 @@ require "hq/graphql/resource/mutation"
|
|
6
5
|
module HQ
|
7
6
|
module GraphQL
|
8
7
|
module Resource
|
9
|
-
extend T::Helpers
|
10
|
-
|
11
8
|
def self.included(base)
|
12
9
|
super
|
13
10
|
::HQ::GraphQL.types << base
|
14
11
|
base.include Scalars
|
15
12
|
base.include ::GraphQL::Types
|
13
|
+
base.extend ClassMethods
|
16
14
|
end
|
17
15
|
|
18
16
|
module ClassMethods
|
@@ -294,8 +292,6 @@ module HQ
|
|
294
292
|
end
|
295
293
|
end
|
296
294
|
end
|
297
|
-
|
298
|
-
mixes_in_class_methods(ClassMethods)
|
299
295
|
end
|
300
296
|
end
|
301
297
|
end
|
data/lib/hq/graphql/scalars.rb
CHANGED
data/lib/hq/graphql/schema.rb
CHANGED
@@ -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/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,16 @@ 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
|
-
|
58
|
-
|
59
|
-
|
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
|
+
|
75
|
+
def find_type(klass)
|
76
|
+
::HQ::GraphQL.resource_lookup(klass) || ::HQ::GraphQL.types.detect { |t| t.model_klass == klass }
|
60
77
|
end
|
61
78
|
end
|
62
79
|
end
|
data/lib/hq/graphql/version.rb
CHANGED
data/lib/hq/graphql.rb
CHANGED
@@ -1,47 +1,40 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
require "rails"
|
5
4
|
require "graphql"
|
6
5
|
require "graphql/batch"
|
7
|
-
require "sorbet-runtime"
|
8
6
|
require "hq/graphql/field"
|
9
7
|
require "hq/graphql/config"
|
10
8
|
|
11
9
|
module HQ
|
12
10
|
module GraphQL
|
13
|
-
extend T::Sig
|
14
|
-
extend T::Generic
|
15
|
-
|
16
|
-
@config = T.let(::HQ::GraphQL::Config.new, ::HQ::GraphQL::Config)
|
17
|
-
|
18
|
-
sig { returns(::HQ::GraphQL::Config) }
|
19
11
|
def self.config
|
20
|
-
@config
|
12
|
+
@config ||= ::HQ::GraphQL::Config.new
|
21
13
|
end
|
22
14
|
|
23
15
|
def self.configure(&block)
|
24
16
|
config.instance_eval(&block)
|
25
17
|
end
|
26
18
|
|
27
|
-
sig { params(action: T.untyped, object: T.untyped, context: ::GraphQL::Query::Context).returns(T::Boolean) }
|
28
19
|
def self.authorized?(action, object, context)
|
29
|
-
!config.authorize ||
|
20
|
+
!config.authorize || config.authorize.call(action, object, context)
|
30
21
|
end
|
31
22
|
|
32
|
-
sig { params(action: T.untyped, field: ::HQ::GraphQL::Field, object: T.untyped, context: ::GraphQL::Query::Context).returns(T::Boolean) }
|
33
23
|
def self.authorize_field(action, field, object, context)
|
34
|
-
!config.authorize_field ||
|
24
|
+
!config.authorize_field || config.authorize_field.call(action, field, object, context)
|
35
25
|
end
|
36
26
|
|
37
|
-
sig { params(scope: T.untyped, context: ::GraphQL::Query::Context).returns(T.untyped) }
|
38
27
|
def self.default_scope(scope, context)
|
39
28
|
config.default_scope.call(scope, context)
|
40
29
|
end
|
41
30
|
|
42
|
-
|
31
|
+
def self.resource_lookup(klass)
|
32
|
+
config.resource_lookup.call(klass)
|
33
|
+
end
|
34
|
+
|
43
35
|
def self.reset!
|
44
36
|
@root_queries = nil
|
37
|
+
@enums = nil
|
45
38
|
@types = nil
|
46
39
|
::HQ::GraphQL::Inputs.reset!
|
47
40
|
::HQ::GraphQL::Types.reset!
|
@@ -51,7 +44,10 @@ module HQ
|
|
51
44
|
@root_queries ||= Set.new
|
52
45
|
end
|
53
46
|
|
54
|
-
|
47
|
+
def self.enums
|
48
|
+
@enums ||= Set.new
|
49
|
+
end
|
50
|
+
|
55
51
|
def self.types
|
56
52
|
@types ||= Set.new
|
57
53
|
end
|
@@ -61,6 +57,7 @@ end
|
|
61
57
|
require "hq/graphql/active_record_extensions"
|
62
58
|
require "hq/graphql/scalars"
|
63
59
|
require "hq/graphql/comparator"
|
60
|
+
require "hq/graphql/enum"
|
64
61
|
require "hq/graphql/inputs"
|
65
62
|
require "hq/graphql/input_object"
|
66
63
|
require "hq/graphql/loaders"
|
data/lib/hq-graphql.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.0.9
|
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-05-13 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
|
@@ -284,6 +250,7 @@ files:
|
|
284
250
|
- lib/hq/graphql/comparator.rb
|
285
251
|
- lib/hq/graphql/config.rb
|
286
252
|
- lib/hq/graphql/engine.rb
|
253
|
+
- lib/hq/graphql/enum.rb
|
287
254
|
- lib/hq/graphql/field.rb
|
288
255
|
- lib/hq/graphql/input_object.rb
|
289
256
|
- lib/hq/graphql/inputs.rb
|