graphql_model_mapper 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: :shallow, type_case: :camelize)
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.use_authorize
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
- end
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 100
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 :welcomeQuery, types.String, hash_key: :welcomeMutation do
40
- resolve -> (obj, args, ctx){
41
- {
42
- welcomeQuery: "this is a placeholder mutation in case you do not have access to other queries"
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 :welcomeMutation, types.String, hash_key: :welcomeMutation do
63
- resolve -> (obj, args, ctx){
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.authorized?(ctx, model_name, access, roles=nil)
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
@@ -1,3 +1,3 @@
1
1
  module GraphqlModelMapper
2
- VERSION = "0.0.6"
2
+ VERSION = "0.1.0"
3
3
  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.6
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-14 00:00:00.000000000 Z
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