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.
@@ -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