graphql_model_mapper 0.0.6 → 0.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/Gemfile.lock +1 -1
- data/README.md +273 -272
- data/lib/graphql_model_mapper.rb +22 -10
- data/lib/graphql_model_mapper/custom_type.rb +4 -0
- data/lib/graphql_model_mapper/mapper_type.rb +195 -187
- data/lib/graphql_model_mapper/mutation.rb +78 -35
- data/lib/graphql_model_mapper/query.rb +126 -22
- data/lib/graphql_model_mapper/resolve.rb +256 -210
- data/lib/graphql_model_mapper/schema.rb +98 -20
- data/lib/graphql_model_mapper/utility.rb +20 -2
- data/lib/graphql_model_mapper/version.rb +1 -1
- metadata +3 -2
@@ -1,12 +1,32 @@
|
|
1
1
|
module GraphqlModelMapper
|
2
|
-
def self.Schema(log_query_depth: false, log_query_complexity: false, use_backtrace: false, use_authorize: false, nesting_strategy: :
|
2
|
+
def self.Schema(log_query_depth: false, log_query_complexity: false, use_backtrace: false, use_authorize: false, nesting_strategy: :deep, type_case: :camelize, max_page_size: 100, scan_for_polymorphic_associations: false, mutation_resolve_wrapper: nil, query_resolve_wrapper: nil, bidirectional_pagination: false, default_nodes_field: false)
|
3
3
|
|
4
4
|
return GraphqlModelMapper.get_constant("GraphqlModelMapperSchema".upcase) if GraphqlModelMapper.defined_constant?("GraphqlModelMapperSchema".upcase)
|
5
5
|
GraphqlModelMapper.use_authorize = use_authorize
|
6
6
|
GraphqlModelMapper.nesting_strategy = nesting_strategy
|
7
7
|
GraphqlModelMapper.type_case = type_case
|
8
|
+
GraphqlModelMapper.max_page_size = max_page_size
|
9
|
+
GraphqlModelMapper.scan_for_polymorphic_associations = scan_for_polymorphic_associations
|
10
|
+
GraphqlModelMapper.default_nodes_field = default_nodes_field
|
11
|
+
GraphqlModelMapper.bidirectional_pagination = bidirectional_pagination
|
8
12
|
|
9
|
-
if GraphqlModelMapper
|
13
|
+
if query_resolve_wrapper && query_resolve_wrapper < GraphqlModelMapper::Resolve::ResolveWrapper
|
14
|
+
GraphqlModelMapper.query_resolve_wrapper = query_resolve_wrapper
|
15
|
+
else
|
16
|
+
GraphqlModelMapper.query_resolve_wrapper = GraphqlModelMapper::Resolve::ResolveWrapper
|
17
|
+
end
|
18
|
+
|
19
|
+
if mutation_resolve_wrapper && mutation_resolve_wrapper < GraphqlModelMapper::Resolve::ResolveWrapper
|
20
|
+
GraphqlModelMapper.mutation_resolve_wrapper = mutation_resolve_wrapper
|
21
|
+
else
|
22
|
+
GraphqlModelMapper.mutation_resolve_wrapper = GraphqlModelMapper::Resolve::ResolveWrapper
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
GraphQL::Relay::ConnectionType.bidirectional_pagination = GraphqlModelMapper.bidirectional_pagination
|
27
|
+
GraphQL::Relay::ConnectionType.default_nodes_field = GraphqlModelMapper.default_nodes_field
|
28
|
+
|
29
|
+
#if GraphqlModelMapper.use_authorize
|
10
30
|
metadata_definitions = {
|
11
31
|
authorized: ->(field, authorized_proc) { field.metadata[:authorized_proc] = authorized_proc },
|
12
32
|
model_name: GraphQL::Define.assign_metadata_key(:model_name),
|
@@ -14,13 +34,50 @@ module GraphqlModelMapper
|
|
14
34
|
}
|
15
35
|
GraphQL::Field.accepts_definitions(metadata_definitions)
|
16
36
|
GraphQL::Argument.accepts_definitions(metadata_definitions)
|
17
|
-
|
37
|
+
GraphQL::ObjectType.accepts_definitions(metadata_definitions)
|
38
|
+
#end
|
18
39
|
|
19
40
|
schema = GraphQL::Schema.define do
|
20
41
|
use GraphQL::Backtrace if use_backtrace
|
21
|
-
default_max_page_size
|
42
|
+
default_max_page_size max_page_size.to_i
|
22
43
|
mutation GraphqlModelMapper.MutationType
|
23
44
|
query GraphqlModelMapper.QueryType
|
45
|
+
|
46
|
+
resolve_type ->(type, obj, ctx) {
|
47
|
+
raise GraphQL::ExecutionError.new("unauthorized access: #{obj.class.name}") if !GraphqlModelMapper.authorized?(ctx, obj.class.name)
|
48
|
+
GraphqlModelMapper.get_constant("#{obj.class.name}Output".upcase)
|
49
|
+
}
|
50
|
+
|
51
|
+
# Create UUIDs by joining the type name & ID, then base64-encoding it
|
52
|
+
id_from_object ->(object, type_definition, context) {
|
53
|
+
GraphQL::Schema::UniqueWithinType.encode(type_definition.name, object.id)
|
54
|
+
}
|
55
|
+
|
56
|
+
object_from_id ->(id, context) {
|
57
|
+
type_name, item_id = GraphQL::Schema::UniqueWithinType.decode(id)
|
58
|
+
|
59
|
+
type = GraphqlModelMapper.get_constant(type_name.upcase)
|
60
|
+
raise GraphQL::ExecutionError.new("unknown type for id: #{id}") if type.nil?
|
61
|
+
authorized_proc = type.metadata[:authorized_proc]
|
62
|
+
model_name = type.metadata[:model_name]
|
63
|
+
access_type = type.metadata[:access_type]
|
64
|
+
|
65
|
+
|
66
|
+
raise GraphQL::ExecutionError.new("unauthorized access for id: #{id}") if !authorized_proc.call(context, model_name, access_type)
|
67
|
+
model = model_name.to_s.classify.constantize
|
68
|
+
=begin
|
69
|
+
args = {
|
70
|
+
item_id: item_id
|
71
|
+
}
|
72
|
+
resolver = -> (obj, args, ctx) {
|
73
|
+
items = GraphqlModelMapper::Resolve.query_resolver(obj, args, ctx, nil)
|
74
|
+
}
|
75
|
+
resolve = GraphqlModelMapper::Query.get_resolver(resolver)
|
76
|
+
resolve.call(model, args, context)
|
77
|
+
=end
|
78
|
+
|
79
|
+
model.unscoped.find(item_id)
|
80
|
+
}
|
24
81
|
end
|
25
82
|
|
26
83
|
|
@@ -28,7 +85,7 @@ module GraphqlModelMapper
|
|
28
85
|
schema.query_analyzers << GraphQL::Analysis::QueryComplexity.new { |query, complexity| Rails.logger.info("[******GraphqlModelMapper Query Complexity] #{complexity}")} if log_query_complexity
|
29
86
|
|
30
87
|
GraphqlModelMapper.set_constant("GraphqlModelMapperSchema".upcase, schema)
|
31
|
-
|
88
|
+
GraphqlModelMapper.get_constant("GraphqlModelMapperSchema".upcase)
|
32
89
|
end
|
33
90
|
|
34
91
|
|
@@ -36,13 +93,14 @@ module GraphqlModelMapper
|
|
36
93
|
return GraphQL::ObjectType.define do
|
37
94
|
name 'Query'
|
38
95
|
# create queries for each AR model object
|
39
|
-
field :
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
96
|
+
field :node, GraphQL::Relay::Node.field do
|
97
|
+
description "Fetches an object given its globally unique ID"
|
98
|
+
end
|
99
|
+
|
100
|
+
field :nodes, GraphQL::Relay::Node.plural_field do
|
101
|
+
description "Fetches a list of objects given a list of globally unique IDs"
|
45
102
|
end
|
103
|
+
|
46
104
|
GraphqlModelMapper.schema_queries.each do |f|
|
47
105
|
field f[:name], f[:field] do
|
48
106
|
if GraphqlModelMapper.use_authorize
|
@@ -58,15 +116,10 @@ module GraphqlModelMapper
|
|
58
116
|
def self.MutationType
|
59
117
|
return GraphQL::ObjectType.define do
|
60
118
|
name 'Mutation'
|
61
|
-
|
62
|
-
field :
|
63
|
-
|
64
|
-
|
65
|
-
welcomeMutation: "this is a placeholder mutation in case you do not have access to other mutations"
|
66
|
-
}
|
67
|
-
}
|
68
|
-
end
|
69
|
-
|
119
|
+
|
120
|
+
field :login, GraphqlModelMapper::LOGIN.field
|
121
|
+
field :logout, GraphqlModelMapper::LOGOUT.field
|
122
|
+
|
70
123
|
GraphqlModelMapper.schema_mutations.each do |f|
|
71
124
|
field f[:name], f[:field] do
|
72
125
|
if GraphqlModelMapper.use_authorize
|
@@ -80,6 +133,31 @@ module GraphqlModelMapper
|
|
80
133
|
end
|
81
134
|
end
|
82
135
|
|
136
|
+
GraphqlModelMapper::LOGIN = GraphQL::Relay::Mutation.define do
|
137
|
+
name 'Login'
|
138
|
+
description ''
|
139
|
+
input_field :username, !GraphQL::STRING_TYPE
|
140
|
+
input_field :password, !GraphQL::STRING_TYPE
|
141
|
+
return_field :success, GraphQL::BOOLEAN_TYPE
|
142
|
+
|
143
|
+
resolve -> (obj, args, ctx){
|
144
|
+
{
|
145
|
+
success: true
|
146
|
+
}
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
GraphqlModelMapper::LOGOUT = GraphQL::Relay::Mutation.define do
|
151
|
+
name 'Logout'
|
152
|
+
description ''
|
153
|
+
return_field :success, GraphQL::BOOLEAN_TYPE
|
154
|
+
resolve -> (obj, args, ctx){
|
155
|
+
{
|
156
|
+
success: true
|
157
|
+
}
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
83
161
|
GraphqlModelMapper::GEOMETRY_OBJECT_TYPE = GraphQL::ScalarType.define do
|
84
162
|
name "GeometryObject"
|
85
163
|
description "The Geometry scalar type enables the serialization of Geometry data"
|
@@ -49,7 +49,22 @@ module GraphqlModelMapper
|
|
49
49
|
output.sort
|
50
50
|
end
|
51
51
|
|
52
|
-
def self.
|
52
|
+
def self.log_resolve(ctx, args, generate_error: false)
|
53
|
+
ret_info = {}
|
54
|
+
ret_info[:return_type] = ctx.type.to_s
|
55
|
+
ret_info[:return_fields] = []
|
56
|
+
ctx.type.fields.keys.each do |f|
|
57
|
+
ret_info[:return_fields] << {field: f, field_type: ctx.type.fields[f].type.to_s}
|
58
|
+
end
|
59
|
+
ret_wrap = {}
|
60
|
+
ret_wrap[:input] = args.to_h
|
61
|
+
ret_wrap[:output] = ret_info
|
62
|
+
GraphqlModelMapper.logger.info "***GraphqlModelMapper_resolver_info: #{{resolver_data: ret_wrap}}"
|
63
|
+
GraphQL::ExecutionError.new("resolver info", options: {resolver_data: ret_wrap}) if generate_error
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.authorized?(ctx, model_name, access=:read, roles=nil)
|
67
|
+
|
53
68
|
model = model_name.classify.constantize
|
54
69
|
access = access.to_sym
|
55
70
|
#here it is checking to see if public methods are exposed on items based on the operation being performed
|
@@ -78,8 +93,11 @@ module GraphqlModelMapper
|
|
78
93
|
end
|
79
94
|
end
|
80
95
|
end
|
96
|
+
if !GraphqlModelMapper.use_authorize
|
97
|
+
return true
|
98
|
+
end
|
81
99
|
#implementation specific, here it is using an ability method on the user class plugged into cancan
|
82
|
-
if ctx[:current_user].public_methods.include?(:ability)
|
100
|
+
if ctx && ctx[:current_user].public_methods.include?(:ability)
|
83
101
|
if !ctx[:current_user].ability.can? access, model
|
84
102
|
return false
|
85
103
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_model_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gene Black
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -156,6 +156,7 @@ files:
|
|
156
156
|
- bin/setup
|
157
157
|
- graphql_model_mapper.gemspec
|
158
158
|
- lib/graphql_model_mapper.rb
|
159
|
+
- lib/graphql_model_mapper/custom_type.rb
|
159
160
|
- lib/graphql_model_mapper/mapper_type.rb
|
160
161
|
- lib/graphql_model_mapper/mutation.rb
|
161
162
|
- lib/graphql_model_mapper/query.rb
|