graphql_model_mapper 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile.lock +2 -1
- data/README.md +216 -83
- data/graphql_model_mapper.gemspec +1 -0
- data/lib/graphql_model_mapper.rb +17 -147
- data/lib/graphql_model_mapper/mapper_type.rb +13 -5
- data/lib/graphql_model_mapper/resolve.rb +58 -40
- data/lib/graphql_model_mapper/schema.rb +37 -5
- data/lib/graphql_model_mapper/utility.rb +137 -0
- data/lib/graphql_model_mapper/version.rb +1 -1
- metadata +17 -3
- data/lib/graphql_model_mapper/schema_types.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3de0884a30479b29813d7f124151fb1438942dd
|
4
|
+
data.tar.gz: cc7c0689ccf60fdbe2f85a7f006eef6e3d52891a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f8a77c07c0ac1799dc4997e794413a5c08d4450c6f49aa3ba401adeb3251548167ee1195703c1f58600d2c5e7d4fb3109ed64a49ff14441b8d826158de307b4
|
7
|
+
data.tar.gz: c23e038b5a35f578b82d7aa8d8cfd6499e350f3a504001b925d413d1e930a426891808f04367e583a5d59f70dced5aab6cbe43f4304642cf33f4b9c696058131
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6
|
+
|
7
|
+
## Our Standards
|
8
|
+
|
9
|
+
Examples of behavior that contributes to creating a positive environment include:
|
10
|
+
|
11
|
+
* Using welcoming and inclusive language
|
12
|
+
* Being respectful of differing viewpoints and experiences
|
13
|
+
* Gracefully accepting constructive criticism
|
14
|
+
* Focusing on what is best for the community
|
15
|
+
* Showing empathy towards other community members
|
16
|
+
|
17
|
+
Examples of unacceptable behavior by participants include:
|
18
|
+
|
19
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
20
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
21
|
+
* Public or private harassment
|
22
|
+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
23
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
24
|
+
|
25
|
+
## Our Responsibilities
|
26
|
+
|
27
|
+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
28
|
+
|
29
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
30
|
+
|
31
|
+
## Scope
|
32
|
+
|
33
|
+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
34
|
+
|
35
|
+
## Enforcement
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at geblack@hotmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
38
|
+
|
39
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
40
|
+
|
41
|
+
## Attribution
|
42
|
+
|
43
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
44
|
+
|
45
|
+
[homepage]: http://contributor-covenant.org
|
46
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,7 @@ This project is a work in progress and is in a pre-alpha state. Many thanks to @
|
|
3
3
|
|
4
4
|
The graphql_model_mapper gem facilitates the generation of GraphQL objects based on the definition of your existing ActiveRecord models.
|
5
5
|
|
6
|
-
It has been tested on Rails 3.2, 4.1 and 5.0 using Ruby 2.2.8
|
6
|
+
It has been tested on Rails 3.2, 4.1 and 5.0 using Ruby 2.1.10 and 2.2.8
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -32,87 +32,111 @@ Initially, you will not have any models exposed as GraphQL types. To expose a mo
|
|
32
32
|
|
33
33
|
The default input/output types generated for the model are based on the default settings (which may be overriden by initializing GraphqlModelMapper::GRAPHQL_DEFAULT_TYPES in your own initializer
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
type_key: :update,
|
63
|
-
type_sub_key: :input_type
|
35
|
+
#config/initializers/grapqhql_model_mapper_init.rb
|
36
|
+
GraphqlModelMapper::GRAPHQL_DEFAULT_TYPES = {
|
37
|
+
query: {
|
38
|
+
input_type: {
|
39
|
+
required_attributes: [],
|
40
|
+
excluded_attributes: [],
|
41
|
+
allowed_attributes: [],
|
42
|
+
foreign_keys: true,
|
43
|
+
primary_keys: true,
|
44
|
+
validation_keys: false,
|
45
|
+
association_macro: nil,
|
46
|
+
source_nulls: false,
|
47
|
+
type_key: :query,
|
48
|
+
type_sub_key: :input_type
|
49
|
+
},
|
50
|
+
output_type: {
|
51
|
+
required_attributes: [],
|
52
|
+
excluded_attributes: [],
|
53
|
+
allowed_attributes: [],
|
54
|
+
foreign_keys: true,
|
55
|
+
primary_keys: true,
|
56
|
+
validation_keys: false,
|
57
|
+
association_macro: nil,
|
58
|
+
source_nulls: false,
|
59
|
+
type_key: :query,
|
60
|
+
type_sub_key: :output_type
|
61
|
+
}
|
64
62
|
},
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
63
|
+
update: {
|
64
|
+
input_type: {
|
65
|
+
required_attributes: [],
|
66
|
+
excluded_attributes: [],
|
67
|
+
allowed_attributes: [],
|
68
|
+
foreign_keys: true,
|
69
|
+
primary_keys: true,
|
70
|
+
validation_keys: false,
|
71
|
+
association_macro: nil,
|
72
|
+
source_nulls: false,
|
73
|
+
type_key: :update,
|
74
|
+
type_sub_key: :input_type
|
75
|
+
},
|
76
|
+
output_type: {
|
77
|
+
required_attributes: [],
|
78
|
+
excluded_attributes: [],
|
79
|
+
allowed_attributes: [],
|
80
|
+
foreign_keys: true,
|
81
|
+
primary_keys: true,
|
82
|
+
validation_keys: false,
|
83
|
+
association_macro: nil,
|
84
|
+
source_nulls: true,
|
85
|
+
type_key: :update,
|
86
|
+
type_sub_key: :output_type
|
87
|
+
}
|
88
|
+
},
|
89
|
+
delete: {
|
90
|
+
input_type: {
|
91
|
+
required_attributes: [:id],
|
92
|
+
excluded_attributes: [],
|
93
|
+
allowed_attributes: [:id],
|
94
|
+
foreign_keys: false,
|
95
|
+
primary_keys: true,
|
96
|
+
validation_keys: false,
|
97
|
+
association_macro: nil,
|
98
|
+
source_nulls: false,
|
99
|
+
type_key: :delete,
|
100
|
+
type_sub_key: :input_type
|
101
|
+
},
|
102
|
+
output_type: {
|
103
|
+
required_attributes: [],
|
104
|
+
excluded_attributes: [],
|
105
|
+
allowed_attributes: [],
|
106
|
+
foreign_keys: false,
|
107
|
+
primary_keys: true,
|
108
|
+
validation_keys: false,
|
109
|
+
association_macro: nil,
|
110
|
+
source_nulls: true,
|
111
|
+
type_key: :delete,
|
112
|
+
type_sub_key: :output_type
|
113
|
+
}
|
104
114
|
},
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
115
|
+
create: {
|
116
|
+
input_type: {
|
117
|
+
required_attributes: [],
|
118
|
+
excluded_attributes: [],
|
119
|
+
allowed_attributes: [],
|
120
|
+
foreign_keys: true,
|
121
|
+
primary_keys: false,
|
122
|
+
validation_keys: false,
|
123
|
+
association_macro: :has_many,
|
124
|
+
source_nulls: false,
|
125
|
+
type_key: :create,
|
126
|
+
type_sub_key: :input_type
|
127
|
+
},
|
128
|
+
output_type: {
|
129
|
+
required_attributes: [],
|
130
|
+
excluded_attributes: [],
|
131
|
+
allowed_attributes: [],
|
132
|
+
foreign_keys: true,
|
133
|
+
primary_keys: true,
|
134
|
+
validation_keys: false,
|
135
|
+
association_macro: nil,
|
136
|
+
source_nulls: true,
|
137
|
+
type_key: :create,
|
138
|
+
type_sub_key: :output_type
|
139
|
+
}
|
116
140
|
}
|
117
141
|
}
|
118
142
|
|
@@ -120,7 +144,7 @@ or individually by using the
|
|
120
144
|
|
121
145
|
graphql_type
|
122
146
|
|
123
|
-
macro attribute on the model, passing the individual settings that differ from the defaults. i.e.
|
147
|
+
macro attribute on the model, passing the individual settings that differ from the defaults. These will be merged into the default values. i.e.
|
124
148
|
|
125
149
|
|
126
150
|
graphql_types query: {
|
@@ -153,6 +177,115 @@ macro attribute on the model, passing the individual settings that differ from t
|
|
153
177
|
}
|
154
178
|
}
|
155
179
|
|
180
|
+
or you can specify the **graphql_types** attribute on the model and initialize your own constant for the model in an initializer, these settings will not be merged into the default settings, so you will need to fully elucidate the types
|
181
|
+
|
182
|
+
#config/initializers/grapqhql_model_mapper_init.rb
|
183
|
+
GraphqlModelMapper::[YOUR_MODEL_NAME_CLASSIFIED_AND_CAPITALIZED]_GRAPHQL_DEFAULT_TYPES = {
|
184
|
+
query: {
|
185
|
+
input_type: {
|
186
|
+
required_attributes: [],
|
187
|
+
excluded_attributes: [],
|
188
|
+
allowed_attributes: [],
|
189
|
+
foreign_keys: true,
|
190
|
+
primary_keys: true,
|
191
|
+
validation_keys: false,
|
192
|
+
association_macro: nil,
|
193
|
+
source_nulls: false,
|
194
|
+
type_key: :query,
|
195
|
+
type_sub_key: :input_type
|
196
|
+
},
|
197
|
+
output_type: {
|
198
|
+
required_attributes: [],
|
199
|
+
excluded_attributes: [],
|
200
|
+
allowed_attributes: [],
|
201
|
+
foreign_keys: true,
|
202
|
+
primary_keys: true,
|
203
|
+
validation_keys: false,
|
204
|
+
association_macro: nil,
|
205
|
+
source_nulls: false,
|
206
|
+
type_key: :query,
|
207
|
+
type_sub_key: :output_type
|
208
|
+
}
|
209
|
+
},
|
210
|
+
update: {
|
211
|
+
input_type: {
|
212
|
+
required_attributes: [],
|
213
|
+
excluded_attributes: [],
|
214
|
+
allowed_attributes: [],
|
215
|
+
foreign_keys: true,
|
216
|
+
primary_keys: true,
|
217
|
+
validation_keys: false,
|
218
|
+
association_macro: nil,
|
219
|
+
source_nulls: false,
|
220
|
+
type_key: :update,
|
221
|
+
type_sub_key: :input_type
|
222
|
+
},
|
223
|
+
output_type: {
|
224
|
+
required_attributes: [],
|
225
|
+
excluded_attributes: [],
|
226
|
+
allowed_attributes: [],
|
227
|
+
foreign_keys: true,
|
228
|
+
primary_keys: true,
|
229
|
+
validation_keys: false,
|
230
|
+
association_macro: nil,
|
231
|
+
source_nulls: true,
|
232
|
+
type_key: :update,
|
233
|
+
type_sub_key: :output_type
|
234
|
+
}
|
235
|
+
},
|
236
|
+
delete: {
|
237
|
+
input_type: {
|
238
|
+
required_attributes: [:id],
|
239
|
+
excluded_attributes: [],
|
240
|
+
allowed_attributes: [:id],
|
241
|
+
foreign_keys: false,
|
242
|
+
primary_keys: true,
|
243
|
+
validation_keys: false,
|
244
|
+
association_macro: nil,
|
245
|
+
source_nulls: false,
|
246
|
+
type_key: :delete,
|
247
|
+
type_sub_key: :input_type
|
248
|
+
},
|
249
|
+
output_type: {
|
250
|
+
required_attributes: [],
|
251
|
+
excluded_attributes: [],
|
252
|
+
allowed_attributes: [],
|
253
|
+
foreign_keys: false,
|
254
|
+
primary_keys: true,
|
255
|
+
validation_keys: false,
|
256
|
+
association_macro: nil,
|
257
|
+
source_nulls: true,
|
258
|
+
type_key: :delete,
|
259
|
+
type_sub_key: :output_type
|
260
|
+
}
|
261
|
+
},
|
262
|
+
create: {
|
263
|
+
input_type: {
|
264
|
+
required_attributes: [],
|
265
|
+
excluded_attributes: [],
|
266
|
+
allowed_attributes: [],
|
267
|
+
foreign_keys: true,
|
268
|
+
primary_keys: false,
|
269
|
+
validation_keys: false,
|
270
|
+
association_macro: :has_many,
|
271
|
+
source_nulls: false,
|
272
|
+
type_key: :create,
|
273
|
+
type_sub_key: :input_type
|
274
|
+
},
|
275
|
+
output_type: {
|
276
|
+
required_attributes: [],
|
277
|
+
excluded_attributes: [],
|
278
|
+
allowed_attributes: [],
|
279
|
+
foreign_keys: true,
|
280
|
+
primary_keys: true,
|
281
|
+
validation_keys: false,
|
282
|
+
association_macro: nil,
|
283
|
+
source_nulls: true,
|
284
|
+
type_key: :create,
|
285
|
+
type_sub_key: :output_type
|
286
|
+
}
|
287
|
+
}
|
288
|
+
}
|
156
289
|
## Other Options
|
157
290
|
|
158
291
|
The query and mutation objects have a default resolver defined that may be sufficient for your needs (with the exception of the create mutation which most likely will not be adequate for your implementation, currently it simply validates the input and does not attempt to add the record).
|
@@ -193,7 +326,7 @@ When returning items to populate the appropriate output type, return them as a h
|
|
193
326
|
or
|
194
327
|
|
195
328
|
resolver: -> (obj, inputs, ctx){
|
196
|
-
|
329
|
+
item = YourClass.method_that_returns_an_item(obj, inputs, ctx, name)
|
197
330
|
{
|
198
331
|
item: item
|
199
332
|
}
|
@@ -354,7 +487,7 @@ so you may access and test your GraphQL queries. It is located at https://github
|
|
354
487
|
|
355
488
|
you can then reference your previously assigned schema in app/controllers/graphql_controller.rb
|
356
489
|
|
357
|
-
#app/controllers/graphql_controller
|
490
|
+
#app/controllers/graphql_controller.rb
|
358
491
|
class GraphqlController < ApplicationController
|
359
492
|
def execute
|
360
493
|
variables = ensure_hash(params[:variables])
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
33
|
spec.required_ruby_version = '>= 2.1'
|
34
|
+
spec.add_runtime_dependency "graphql", ['>= 1.7.5']
|
34
35
|
spec.add_runtime_dependency "activesupport", ['>= 3.2.22.5']
|
35
36
|
spec.add_runtime_dependency "activemodel", ['>= 3.2.22.5']
|
36
37
|
spec.add_runtime_dependency "activerecord", ['>= 3.2.22.5']
|
data/lib/graphql_model_mapper.rb
CHANGED
@@ -4,6 +4,7 @@ require "graphql_model_mapper/mutation"
|
|
4
4
|
require "graphql_model_mapper/query"
|
5
5
|
require "graphql_model_mapper/resolve"
|
6
6
|
require "graphql_model_mapper/schema"
|
7
|
+
require "graphql_model_mapper/utility"
|
7
8
|
require "graphql_model_mapper/version"
|
8
9
|
require 'graphql_model_mapper/railtie' if defined?(Rails)
|
9
10
|
|
@@ -11,6 +12,10 @@ module GraphqlModelMapper
|
|
11
12
|
mattr_accessor :type_case
|
12
13
|
mattr_accessor :nesting_strategy
|
13
14
|
mattr_accessor :use_authorize
|
15
|
+
|
16
|
+
@@type_case = :camelize
|
17
|
+
@@nesting_strategy = :shallow
|
18
|
+
@@use_authorize = false
|
14
19
|
|
15
20
|
class << self
|
16
21
|
attr_writer :logger
|
@@ -22,207 +27,72 @@ module GraphqlModelMapper
|
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
|
-
@@type_case = :camelize
|
26
|
-
@@nesting_strategy = :shallow
|
27
|
-
@@use_authorize = false
|
28
30
|
|
29
31
|
def self.included(klazz)
|
30
32
|
klazz.extend GraphqlModelMapper_Macros
|
31
33
|
end
|
32
34
|
|
33
35
|
module GraphqlModelMapper_Macros
|
34
|
-
protected
|
35
36
|
|
36
|
-
|
37
|
+
protected
|
38
|
+
|
39
|
+
def graphql_types(query: {}, update: {}, delete: {}, create: {})
|
40
|
+
name = self.name
|
37
41
|
define_singleton_method(:graphql_types) do
|
38
42
|
GraphqlModelMapper::MapperType.graphql_types(name: name, query: query, update: update, delete: delete, create: create)
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
|
-
def graphql_update(
|
43
|
-
GraphqlModelMapper.logger.info "********************update"
|
46
|
+
def graphql_update(description:"", resolver: -> (obj, inputs, ctx){
|
44
47
|
item = GraphqlModelMapper::Resolve.update_resolver(obj, inputs, ctx, name)
|
45
48
|
{
|
46
49
|
item: item
|
47
50
|
}
|
48
51
|
})
|
52
|
+
name = self.name
|
49
53
|
define_singleton_method(:graphql_update) do
|
50
54
|
GraphqlModelMapper::Mutation.graphql_update(name: name, description: description, resolver: resolver)
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
def graphql_delete(
|
55
|
-
GraphqlModelMapper.logger.info "********************delete"
|
58
|
+
def graphql_delete(description:"", resolver: -> (obj, inputs, ctx){
|
56
59
|
items = GraphqlModelMapper::Resolve.delete_resolver(obj, inputs, ctx, name)
|
57
60
|
{
|
58
61
|
total: items.length,
|
59
62
|
items: items
|
60
63
|
}
|
61
64
|
}, arguments: [], scope_methods: [])
|
65
|
+
name = self.name
|
62
66
|
define_singleton_method(:graphql_delete) do
|
63
67
|
GraphqlModelMapper::Mutation.graphql_delete(name: name, description: description, resolver: resolver, scope_methods: scope_methods)
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
|
-
def graphql_create(
|
68
|
-
GraphqlModelMapper.logger.info "********************create"
|
71
|
+
def graphql_create(description:"", resolver: -> (obj, args, ctx){
|
69
72
|
item = GraphqlModelMapper::Resolve.create_resolver(obj, args, ctx, name)
|
70
73
|
{
|
71
74
|
item: item
|
72
75
|
}
|
73
76
|
})
|
77
|
+
name = self.name
|
74
78
|
define_singleton_method(:graphql_create) do
|
75
79
|
GraphqlModelMapper::Mutation.graphql_create(name: name, description: description, resolver: resolver)
|
76
80
|
end
|
77
81
|
end
|
78
82
|
|
79
|
-
def graphql_query(
|
83
|
+
def graphql_query(description: "", resolver: -> (obj, args, ctx) {
|
80
84
|
items = GraphqlModelMapper::Resolve.query_resolver(obj, args, ctx, name)
|
81
85
|
{
|
82
86
|
items: items,
|
83
87
|
total: items.length
|
84
88
|
}
|
85
89
|
}, arguments: [], scope_methods: [])
|
90
|
+
name = self.name
|
86
91
|
define_singleton_method(:graphql_query) do
|
87
92
|
GraphqlModelMapper::Query.graphql_query(name: name, description: description, resolver: resolver, scope_methods: scope_methods)
|
88
93
|
end
|
89
94
|
end
|
90
95
|
end
|
91
|
-
|
92
|
-
def self.implementations
|
93
|
-
Rails.application.eager_load!
|
94
|
-
ActiveRecord::Base.descendants.each.select do |clz|
|
95
|
-
begin
|
96
|
-
clz.included_modules.include?(GraphqlModelMapper) && (clz.public_methods.include?(:graphql_query) || clz.public_methods.include?(:graphql_update) || clz.public_methods.include?(:graphql_delete) || clz.public_methods.include?(:graphql_create) || clz.public_methods.include?(:graphql_types))
|
97
|
-
rescue
|
98
|
-
# it is okay that this is empty - just covering the possibility
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.schema_queries
|
104
|
-
fields = []
|
105
|
-
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_query)}.each { |t|
|
106
|
-
fields << { :name =>GraphqlModelMapper.get_type_case(t.name, false).to_sym, :field => t.graphql_query, :model_name=>t.name, :access_type=>:query }
|
107
|
-
}
|
108
|
-
fields
|
109
|
-
end
|
110
|
-
|
111
|
-
def self.schema_mutations
|
112
|
-
fields = []
|
113
|
-
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_create)}.each { |t|
|
114
|
-
fields << {:name => GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(t.name)}Create", false).to_sym, :field=> t.graphql_create, :model_name=>t.name, :access_type=>:create }
|
115
|
-
}
|
116
|
-
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_update)}.each { |t|
|
117
|
-
fields << {:name =>GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(t.name)}Update", false).to_sym, :field=>t.graphql_update, :model_name=>t.name, :access_type=>:update }
|
118
|
-
}
|
119
|
-
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_delete)}.each { |t|
|
120
|
-
fields << {:name =>GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(t.name)}Delete", false).to_sym, :field=>t.graphql_delete, :model_name=>t.name, :access_type=>:delete }
|
121
|
-
}
|
122
|
-
fields
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.select_list(model_name, classes=[])
|
126
|
-
model = model_name.classify.constantize
|
127
|
-
output = []
|
128
|
-
columns = model.columns_hash.keys.map{|m| "#{model.name.underscore.pluralize}.#{m}"}
|
129
|
-
relation_includes = model.reflect_on_all_associations.select{|t| begin t.klass rescue next end}.select{|t| !t.options[:polymorphic]}.map{|m| "#{model.name.underscore.pluralize}.#{m.name}"}
|
130
|
-
relations = model.reflect_on_all_associations.select{|t| begin t.klass rescue next end}.select{|t| !t.options[:polymorphic]}
|
131
|
-
relations.each do |a|
|
132
|
-
if !classes.include?(a.klass.name)
|
133
|
-
classes << a.klass.name
|
134
|
-
output = output + GraphqlModelMapper.select_list(a.klass.name, classes)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
output << relation_includes + columns
|
138
|
-
output.sort
|
139
|
-
end
|
140
|
-
|
141
|
-
def self.authorized?(ctx, model_name, access, roles=nil)
|
142
|
-
model = model_name.classify.constantize
|
143
|
-
access = access.to_sym
|
144
|
-
#here it is checking to see if public methods are exposed on items based on the operation being performed
|
145
|
-
if (access && access == :read) || (access && access == :query)
|
146
|
-
access = :read
|
147
|
-
if !model.public_methods.include?(:graphql_query)
|
148
|
-
return false
|
149
|
-
end
|
150
|
-
elsif access && access == :create
|
151
|
-
if !model.public_methods.include?(:graphql_create)
|
152
|
-
return false
|
153
|
-
end
|
154
|
-
elsif access && access == :update
|
155
|
-
if !model.public_methods.include?(:graphql_update)
|
156
|
-
return false
|
157
|
-
end
|
158
|
-
elsif access && access == :delete
|
159
|
-
if !model.public_methods.include?(:graphql_delete)
|
160
|
-
return false
|
161
|
-
end
|
162
|
-
end
|
163
|
-
if roles && roles.length > 0
|
164
|
-
roles.each do |r|
|
165
|
-
if !ctx[:current_user].hash_role?(role)
|
166
|
-
return false
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
#implementation specific, here it is using an ability method on the user class plugged into cancan
|
171
|
-
if ctx[:current_user].public_methods.include?(:ability)
|
172
|
-
if !ctx[:current_user].ability.can? access, model
|
173
|
-
return false
|
174
|
-
end
|
175
|
-
end
|
176
|
-
true
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.get_type_name(classname, lowercase_first_letter=false)
|
180
|
-
str = "#{classname.classify.demodulize}"
|
181
|
-
if lowercase_first_letter && str.length > 0
|
182
|
-
str = str[0].downcase + str[1..-1]
|
183
|
-
end
|
184
|
-
str
|
185
|
-
end
|
186
|
-
|
187
|
-
def self.get_type_case(str, uppercase=true)
|
188
|
-
if @@type_case == :camelize
|
189
|
-
if uppercase
|
190
|
-
str.to_s.camelize(:upper)
|
191
|
-
else
|
192
|
-
str.to_s.camelize(:lower)
|
193
|
-
end
|
194
|
-
elsif @@type_case == :underscore
|
195
|
-
if uppercase
|
196
|
-
self.underscore(str)
|
197
|
-
else
|
198
|
-
str.underscore
|
199
|
-
end
|
200
|
-
elsif @@type_case == :classify
|
201
|
-
str
|
202
|
-
else
|
203
|
-
str
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
def self.underscore(str, upcase=true)
|
208
|
-
if upcase
|
209
|
-
str.split('_').map {|w| w.capitalize}.join('_')
|
210
|
-
else
|
211
|
-
str.underscore
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def self.get_constant(type_name)
|
216
|
-
GraphqlModelMapper.const_get(type_name.upcase)
|
217
|
-
end
|
218
|
-
|
219
|
-
def self.set_constant(type_name, type)
|
220
|
-
GraphqlModelMapper.const_set(type_name.upcase, type)
|
221
|
-
end
|
222
|
-
|
223
|
-
def self.defined_constant?(type_name)
|
224
|
-
GraphqlModelMapper.const_defined?(type_name.upcase)
|
225
|
-
end
|
226
96
|
end
|
227
97
|
|
228
98
|
ActiveRecord::Base.send(:include, GraphqlModelMapper) if defined?(ActiveRecord)
|
@@ -7,16 +7,17 @@ module GraphqlModelMapper
|
|
7
7
|
delete: {},
|
8
8
|
create: {}
|
9
9
|
)
|
10
|
-
typesuffix = method(__method__).parameters.map { |arg| eval arg[1].to_s }.hash.abs.to_i.to_s
|
11
|
-
|
12
|
-
|
10
|
+
#typesuffix = method(__method__).parameters.map { |arg| eval arg[1].to_s }.hash.abs.to_i.to_s
|
11
|
+
GraphqlModelMapper.logger.info("#{name.upcase}") if GraphqlModelMapper.const_defined?("#{name.upcase}_GRAPHQL_DEFAULT_TYPES")
|
12
|
+
return GraphqlModelMapper.get_constant("#{name.upcase}_GRAPHQL_DEFAULT_TYPES") if GraphqlModelMapper.const_defined?("#{name.upcase}_GRAPHQL_DEFAULT_TYPES")
|
13
|
+
#GraphqlModelMapper.logger.info "#{name.upcase}_GRAPHQL_DEFAULT_TYPES"
|
13
14
|
graphql_type = {}
|
14
15
|
graphql_type[:query] = query
|
15
16
|
graphql_type[:update] = update
|
16
17
|
graphql_type[:delete] = delete
|
17
18
|
graphql_type[:create] = create
|
18
19
|
merged_graphql_type = self.graphql_default_types.deep_merge(graphql_type)
|
19
|
-
GraphqlModelMapper.set_constant("#{name.upcase}
|
20
|
+
GraphqlModelMapper.set_constant("#{name.upcase}_GRAPHQL_DEFAULT_TYPES", merged_graphql_type)
|
20
21
|
|
21
22
|
merged_graphql_type
|
22
23
|
end
|
@@ -81,6 +82,7 @@ module GraphqlModelMapper
|
|
81
82
|
begin
|
82
83
|
klass = reflection.klass
|
83
84
|
rescue
|
85
|
+
GraphqlModelMapper.logger.warning("invalid relation #{reflection.name} specified on the #{name} model, the relation class does not exist")
|
84
86
|
next # most likely an invalid association without a class name, skip if other errors are encountered
|
85
87
|
end
|
86
88
|
if reflection.macro == :has_many
|
@@ -124,6 +126,7 @@ module GraphqlModelMapper
|
|
124
126
|
begin
|
125
127
|
klass = reflection.klass
|
126
128
|
rescue
|
129
|
+
GraphqlModelMapper.logger.warning("invalid relation #{reflection.name} specified on the #{name} model, the relation class does not exist")
|
127
130
|
next # most likely an invalid association without a class name, skip if other errors are encountered
|
128
131
|
end
|
129
132
|
if reflection.macro == :has_many
|
@@ -330,7 +333,12 @@ module GraphqlModelMapper
|
|
330
333
|
else
|
331
334
|
case db_sql_type.to_sym #these are strings not symbols
|
332
335
|
when :geometry, :multipolygon, :polygon
|
333
|
-
|
336
|
+
case db_type
|
337
|
+
when :string
|
338
|
+
nullable ? GraphqlModelMapper::GEOMETRY_OBJECT_TYPE : !GraphqlModelMapper::GEOMETRY_OBJECT_TYPE
|
339
|
+
else
|
340
|
+
nullable ? GraphqlModelMapper::GEOMETRY_STRING_TYPE : !GraphqlModelMapper::GEOMETRY_STRING_TYPE
|
341
|
+
end
|
334
342
|
else
|
335
343
|
nullable ? GraphQL::STRING_TYPE : !GraphQL::STRING_TYPE
|
336
344
|
end
|
@@ -20,7 +20,9 @@ module GraphqlModelMapper
|
|
20
20
|
with_deleted_allowed = classmethods.include?(:with_deleted)
|
21
21
|
raise GraphQL::ExecutionError.new("error: invalid usage of 'with_deleted', 'with_deleted' method does not exist on '#{ctx.field.name.classify}'") unless with_deleted_allowed
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
|
+
implied_includes = self.get_implied_includes(name.classify.constantize, ctx.ast_node)
|
25
|
+
|
24
26
|
if !implied_includes.empty?
|
25
27
|
obj_context = obj_context.includes(implied_includes)
|
26
28
|
if Rails.version.split(".").first.to_i > 3
|
@@ -99,50 +101,66 @@ module GraphqlModelMapper
|
|
99
101
|
item
|
100
102
|
end
|
101
103
|
|
104
|
+
def self.using_relay_pagination?(selection)
|
105
|
+
selection.name == 'edges'
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.using_is_items_collection?(selection)
|
109
|
+
selection.name == 'items'
|
110
|
+
end
|
102
111
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
# base field names that have no parent, get the lowest number parent_line on the associated field names
|
110
|
-
a = a.select{|o| o[:parent_line] == a.map{|v| v[:parent_line]}.sort.first}
|
111
|
-
else
|
112
|
-
a = field_names
|
113
|
-
end
|
114
|
-
final_out = []
|
115
|
-
a.each do |b|
|
116
|
-
out = []
|
117
|
-
child_relations = org_field_names.select{|g| g[:parent_line] == b[:line]}
|
118
|
-
if !child_relations.empty?
|
119
|
-
children = GraphqlModelMapper::Resolve.get_implied_includes(nil, child_relations, false, org_field_names, resolve_fields)
|
120
|
-
if children.empty?
|
121
|
-
out << b[:name].to_sym if ![:edges, :node].include?(b[:name].to_sym)
|
122
|
-
else
|
123
|
-
if ![:edges, :node].include?(b[:name].to_sym)
|
124
|
-
out << { b[:name].to_sym => children.flatten }
|
125
|
-
else
|
126
|
-
out = children.flatten
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
if resolve_fields && out.empty?
|
131
|
-
out << b[:name].to_sym
|
132
|
-
end
|
133
|
-
final_out << out if !out.empty?
|
134
|
-
end
|
135
|
-
final_out
|
112
|
+
def self.using_nodes_pagination?(selection)
|
113
|
+
selection.name == 'nodes'
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.has_reflection_with_name?(class_name, selection_name)
|
117
|
+
class_name.reflect_on_all_associations.select{|m|m.name == selection_name.to_sym}.present?
|
136
118
|
end
|
137
119
|
|
138
|
-
def self.
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
120
|
+
def self.map_relay_pagination_depencies(class_name, selection, dependencies)
|
121
|
+
node_selection = selection.selections.find { |sel| sel.name == 'node' }
|
122
|
+
|
123
|
+
if node_selection.present?
|
124
|
+
get_implied_includes(class_name, node_selection, dependencies)
|
125
|
+
else
|
126
|
+
dependencies
|
127
|
+
end
|
144
128
|
end
|
145
129
|
|
130
|
+
def self.get_implied_includes(class_name, ast_node, dependencies={})
|
131
|
+
ast_node.selections.each do |selection|
|
132
|
+
name = selection.name
|
133
|
+
|
134
|
+
if using_relay_pagination?(selection)
|
135
|
+
map_relay_pagination_depencies(class_name, selection, dependencies)
|
136
|
+
next
|
137
|
+
end
|
138
|
+
|
139
|
+
if using_nodes_pagination?(selection)
|
140
|
+
get_implied_includes(class_name, selection, dependencies)
|
141
|
+
next
|
142
|
+
end
|
143
|
+
|
144
|
+
if using_is_items_collection?(selection)
|
145
|
+
get_implied_includes(class_name, selection, dependencies)
|
146
|
+
next
|
147
|
+
end
|
148
|
+
|
149
|
+
if has_reflection_with_name?(class_name, name)
|
150
|
+
begin
|
151
|
+
current_class_name = selection.name.singularize.classify.constantize
|
152
|
+
dependencies[name] = get_implied_includes(current_class_name, selection)
|
153
|
+
rescue NameError
|
154
|
+
selection_name = class_name.reflections.with_indifferent_access[selection.name].options[:class_name]
|
155
|
+
current_class_name = selection_name.singularize.classify.constantize
|
156
|
+
dependencies[selection.name.to_sym] = get_implied_includes(current_class_name, selection)
|
157
|
+
next
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
dependencies
|
162
|
+
end
|
163
|
+
|
146
164
|
|
147
165
|
def self.nested_update(ctx, model_name, inputs, child_name=nil, child_id=nil, parent_name=nil, parent_id=nil, klass_name=nil)
|
148
166
|
model = model_name.classify.constantize
|
@@ -80,20 +80,52 @@ module GraphqlModelMapper
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
GraphqlModelMapper::
|
84
|
-
name "
|
83
|
+
GraphqlModelMapper::GEOMETRY_OBJECT_TYPE = GraphQL::ScalarType.define do
|
84
|
+
name "GeometryObject"
|
85
85
|
description "The Geometry scalar type enables the serialization of Geometry data"
|
86
|
-
|
86
|
+
require 'geo_ruby/geojson' if !defined?(GeoRuby).nil?
|
87
|
+
|
87
88
|
coerce_input ->(value, ctx) do
|
88
89
|
begin
|
89
|
-
value.nil?
|
90
|
+
if value.nil?
|
91
|
+
nil
|
92
|
+
elsif !defined?(GeoRuby::GeojsonParser).nil?
|
93
|
+
GeoRuby::SimpleFeatures::Geometry.from_geojson(value)
|
94
|
+
elsif !defined?(RGeo::GeoJSON).nil?
|
95
|
+
RGeo::GeoJSON.decode(value, json_parser: :json)
|
96
|
+
else
|
97
|
+
raise ArgumentError
|
98
|
+
end
|
90
99
|
rescue ArgumentError
|
91
100
|
raise GraphQL::CoercionError, "cannot coerce `#{value.inspect}` to json"
|
92
101
|
end
|
93
102
|
end
|
94
|
-
coerce_result ->(value, ctx) { value.nil? ? "" : value.to_json }
|
103
|
+
coerce_result ->(value, ctx) { (value.nil? ? "" : (defined?(GeoRuby) == "constant" && value.kind_of?(GeoRuby::SimpleFeatures::Geometry) ? value.to_json : (defined?(RGeo) == "constant" && defined?(RGeo::GeoJSON) == "constant" && RGeo::Geos.is_capi_geos?(value) ? RGeo::GeoJSON.encode(value).to_json : value))) }
|
95
104
|
end
|
96
105
|
|
106
|
+
GraphqlModelMapper::GEOMETRY_STRING_TYPE = GraphQL::ScalarType.define do
|
107
|
+
name "GeometryString"
|
108
|
+
description "The Geometry scalar type enables the serialization of Geometry data"
|
109
|
+
require 'geo_ruby/geojson' if !defined?(GeoRuby).nil?
|
110
|
+
|
111
|
+
coerce_input ->(value, ctx) do
|
112
|
+
begin
|
113
|
+
if value.nil?
|
114
|
+
nil
|
115
|
+
elsif !defined?(GeoRuby::GeojsonParser).nil?
|
116
|
+
GeoRuby::SimpleFeatures::Geometry.from_geojson(value).as_wkt
|
117
|
+
elsif !defined?(RGeo::GeoJSON).nil?
|
118
|
+
RGeo::GeoJSON.decode(value, json_parser: :json).as_text
|
119
|
+
else
|
120
|
+
raise ArgumentError
|
121
|
+
end
|
122
|
+
rescue ArgumentError
|
123
|
+
raise GraphQL::CoercionError, "cannot coerce `#{value.inspect}` to json"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
coerce_result ->(value, ctx) { (value.nil? ? "" : (defined?(GeoRuby) == "constant" && value.kind_of?(GeoRuby::SimpleFeatures::Geometry) ? value.to_json : (defined?(RGeo) == "constant" && defined?(RGeo::GeoJSON) == "constant" && RGeo::Geos.is_capi_geos?(value) ? RGeo::GeoJSON.encode(value).to_json : value))) }
|
127
|
+
end
|
128
|
+
|
97
129
|
GraphqlModelMapper::DATE_TYPE = GraphQL::ScalarType.define do
|
98
130
|
name "Date"
|
99
131
|
description "The Date scalar type enables the serialization of date data to/from iso8601"
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module GraphqlModelMapper
|
2
|
+
|
3
|
+
def self.implementations
|
4
|
+
Rails.application.eager_load!
|
5
|
+
ActiveRecord::Base.descendants.each.select do |clz|
|
6
|
+
begin
|
7
|
+
clz.included_modules.include?(GraphqlModelMapper) && (clz.public_methods.include?(:graphql_query) || clz.public_methods.include?(:graphql_update) || clz.public_methods.include?(:graphql_delete) || clz.public_methods.include?(:graphql_create) || clz.public_methods.include?(:graphql_types))
|
8
|
+
rescue
|
9
|
+
# it is okay that this is empty - just covering the possibility
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.schema_queries
|
15
|
+
fields = []
|
16
|
+
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_query)}.each { |t|
|
17
|
+
fields << { :name =>GraphqlModelMapper.get_type_case(t.name, false).to_sym, :field => t.graphql_query, :model_name=>t.name, :access_type=>:query }
|
18
|
+
}
|
19
|
+
fields
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.schema_mutations
|
23
|
+
fields = []
|
24
|
+
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_create)}.each { |t|
|
25
|
+
fields << {:name => GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(t.name)}Create", false).to_sym, :field=> t.graphql_create, :model_name=>t.name, :access_type=>:create }
|
26
|
+
}
|
27
|
+
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_update)}.each { |t|
|
28
|
+
fields << {:name =>GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(t.name)}Update", false).to_sym, :field=>t.graphql_update, :model_name=>t.name, :access_type=>:update }
|
29
|
+
}
|
30
|
+
GraphqlModelMapper.implementations.select{|t| t.public_methods.include?(:graphql_delete)}.each { |t|
|
31
|
+
fields << {:name =>GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(t.name)}Delete", false).to_sym, :field=>t.graphql_delete, :model_name=>t.name, :access_type=>:delete }
|
32
|
+
}
|
33
|
+
fields
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.select_list(model_name, classes=[])
|
37
|
+
model = model_name.classify.constantize
|
38
|
+
output = []
|
39
|
+
columns = model.columns_hash.keys.map{|m| "#{model.name.underscore.pluralize}.#{m}"}
|
40
|
+
relation_includes = model.reflect_on_all_associations.select{|t| begin t.klass rescue next end}.select{|t| !t.options[:polymorphic]}.map{|m| "#{model.name.underscore.pluralize}.#{m.name}"}
|
41
|
+
relations = model.reflect_on_all_associations.select{|t| begin t.klass rescue next end}.select{|t| !t.options[:polymorphic]}
|
42
|
+
relations.each do |a|
|
43
|
+
if !classes.include?(a.klass.name)
|
44
|
+
classes << a.klass.name
|
45
|
+
output = output + GraphqlModelMapper.select_list(a.klass.name, classes)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
output << relation_includes + columns
|
49
|
+
output.sort
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.authorized?(ctx, model_name, access, roles=nil)
|
53
|
+
model = model_name.classify.constantize
|
54
|
+
access = access.to_sym
|
55
|
+
#here it is checking to see if public methods are exposed on items based on the operation being performed
|
56
|
+
if (access && access == :read) || (access && access == :query)
|
57
|
+
access = :read
|
58
|
+
if !model.public_methods.include?(:graphql_query)
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
elsif access && access == :create
|
62
|
+
if !model.public_methods.include?(:graphql_create)
|
63
|
+
return false
|
64
|
+
end
|
65
|
+
elsif access && access == :update
|
66
|
+
if !model.public_methods.include?(:graphql_update)
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
elsif access && access == :delete
|
70
|
+
if !model.public_methods.include?(:graphql_delete)
|
71
|
+
return false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
if roles && roles.length > 0
|
75
|
+
roles.each do |r|
|
76
|
+
if !ctx[:current_user].hash_role?(role)
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
#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)
|
83
|
+
if !ctx[:current_user].ability.can? access, model
|
84
|
+
return false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.get_type_name(classname, lowercase_first_letter=false)
|
91
|
+
str = "#{classname.classify.demodulize}"
|
92
|
+
if lowercase_first_letter && str.length > 0
|
93
|
+
str = str[0].downcase + str[1..-1]
|
94
|
+
end
|
95
|
+
str
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.get_type_case(str, uppercase=true)
|
99
|
+
if @@type_case == :camelize
|
100
|
+
if uppercase
|
101
|
+
str.to_s.camelize(:upper)
|
102
|
+
else
|
103
|
+
str.to_s.camelize(:lower)
|
104
|
+
end
|
105
|
+
elsif @@type_case == :underscore
|
106
|
+
if uppercase
|
107
|
+
self.underscore(str)
|
108
|
+
else
|
109
|
+
str.underscore
|
110
|
+
end
|
111
|
+
elsif @@type_case == :classify
|
112
|
+
str
|
113
|
+
else
|
114
|
+
str
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.underscore(str, upcase=true)
|
119
|
+
if upcase
|
120
|
+
str.split('_').map {|w| w.capitalize}.join('_')
|
121
|
+
else
|
122
|
+
str.underscore
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.get_constant(type_name)
|
127
|
+
GraphqlModelMapper.const_get(type_name.upcase)
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.set_constant(type_name, type)
|
131
|
+
GraphqlModelMapper.const_set(type_name.upcase, type)
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.defined_constant?(type_name)
|
135
|
+
GraphqlModelMapper.const_defined?(type_name.upcase)
|
136
|
+
end
|
137
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
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.0.6
|
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-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: graphql
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.7.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.7.5
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: activesupport
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,6 +146,7 @@ extra_rdoc_files: []
|
|
132
146
|
files:
|
133
147
|
- ".gitignore"
|
134
148
|
- ".travis.yml"
|
149
|
+
- CODE_OF_CONDUCT.md
|
135
150
|
- Gemfile
|
136
151
|
- Gemfile.lock
|
137
152
|
- LICENSE.txt
|
@@ -147,7 +162,6 @@ files:
|
|
147
162
|
- lib/graphql_model_mapper/railtie.rb
|
148
163
|
- lib/graphql_model_mapper/resolve.rb
|
149
164
|
- lib/graphql_model_mapper/schema.rb
|
150
|
-
- lib/graphql_model_mapper/schema_types.rb
|
151
165
|
- lib/graphql_model_mapper/utility.rb
|
152
166
|
- lib/graphql_model_mapper/version.rb
|
153
167
|
homepage: https://github.com/geneeblack/graphql_model_mapper
|
File without changes
|