graphql-rails-api 0.7.5 → 0.9.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be9e058e2a7ae159b7a92a033421fca0ec479cef7bd59a31519fb1c13ec4b553
4
- data.tar.gz: 13f8555992be67e1491aebcfeb25b8cb995dcb8906b28d27d32f2a5985f3e34b
3
+ metadata.gz: c1751d6f6ae5edf98341bdf30a149cd8aa9ab4dbcb0a627cb25c380cfe15c676
4
+ data.tar.gz: 90c9dc17368d908efb70a8ee55837c3d6b117709762c006eaee18ddcd3a820ff
5
5
  SHA512:
6
- metadata.gz: d4a6e96f941bdb060b1c1e613a1318938fcd11289fd60995500ea0ba46235ef7889e601d200f02a34a7fdfc3e0f24297ac1fe208bde429d1ef089a42eb71ee98
7
- data.tar.gz: a935282ed62517179e467d7cf5b74605c9088336993894ef7b3b90d2db4ca02d59999f0707bd76fbf9508d40fb7eb651640c14860326dd5aac54c6b853af8926
6
+ metadata.gz: 98cd97012f608dea85e6a5417a4d1ab83ddf3cdae9a51473a014a3c4d45769ce928301a9e57ab32a9c65a76df5e3687cead2046e57a829da18a1309ecfc7ff06
7
+ data.tar.gz: d297e02228b4a00c81a9f29eef88c92da12a23698e9e2dc3aa9eab52c3ccf97a471c04aa134d9cb11bb516bc1d2446464ba9b69b8cc0be8d1f84d465deaa2a91
data/README.md CHANGED
@@ -2,8 +2,7 @@
2
2
 
3
3
  `graphql-rails-api` is a gem that provides generators to describe easily your graphql API in a domain driven design way.
4
4
 
5
- Need any help or wanna talk with me about it on slack ? Don't hesitate,
6
- https://bit.ly/2KvV8Pk
5
+ Need any help or wanna talk with me about it on discord : Poilon#5412
7
6
 
8
7
  ## Installation
9
8
 
@@ -17,7 +16,6 @@ rails db:create
17
16
 
18
17
  Add these lines to your application's Gemfile:
19
18
  ```ruby
20
- gem 'graphql'
21
19
  gem 'graphql-rails-api'
22
20
  ```
23
21
 
@@ -245,10 +245,10 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
245
245
  file_name = "app/models/#{model.underscore.singularize}.rb"
246
246
  return if !File.exist?(file_name) || File.read(file_name).include?(line)
247
247
 
248
- line_count = `wc -l "#{file_name}"`.strip.split(' ')[0].to_i
249
-
248
+ file = open(file_name)
249
+ line_count = file.readlines.size
250
250
  line_nb = 0
251
- File.open(file_name).each do |l|
251
+ file.each do |l|
252
252
  line_nb += 1
253
253
  break if l.include?('ApplicationRecord')
254
254
  end
@@ -8,6 +8,7 @@ class GraphqlAllConnectionsGenerator < Rails::Generators::NamedBase
8
8
  end
9
9
 
10
10
  def generate_connection(dir, resource)
11
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
11
12
  File.write(
12
13
  "#{dir}/connection.rb",
13
14
  <<~STRING
@@ -3,7 +3,7 @@ class GraphqlMutationsGenerator < Rails::Generators::NamedBase
3
3
  def generate
4
4
  resource = file_name.underscore.singularize
5
5
  dir = "app/graphql/#{resource.pluralize}/mutations"
6
- system("mkdir -p #{dir}")
6
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
7
7
  generate_create_mutation(dir, resource)
8
8
  generate_update_mutation(dir, resource)
9
9
  generate_destroy_mutation(dir, resource)
@@ -8,14 +8,17 @@ module GraphqlRailsApi
8
8
 
9
9
  def generate_files
10
10
  @app_name = File.basename(Rails.root.to_s).underscore
11
- system('mkdir -p app/graphql/')
12
-
11
+
12
+ folder = 'app/graphql/'
13
+ FileUtils.mkdir_p(folder) unless File.directory?(folder)
14
+
13
15
  write_uuid_extensions_migration
14
16
 
15
17
  write_service
16
18
  write_schema
17
19
  write_query_type
18
20
  write_mutation_type
21
+ write_collection_ids_resolver
19
22
 
20
23
  write_controller
21
24
 
@@ -52,6 +55,25 @@ module GraphqlRailsApi
52
55
  )
53
56
  end
54
57
 
58
+ def write_collection_ids_resolver
59
+ File.write(
60
+ 'app/graphql/collection_ids_resolver.rb',
61
+ <<~STRING
62
+ class CollectionIdsResolver
63
+
64
+ def self.call(obj, _args, ctx)
65
+ if obj.is_a?(OpenStruct)
66
+ obj[ctx.field.name.gsub('_ids', '').pluralize]&.map(&:id)
67
+ else
68
+ obj.send(ctx.field.name)
69
+ end
70
+ end
71
+
72
+ end
73
+ STRING
74
+ )
75
+ end
76
+
55
77
  def write_application_record_methods
56
78
  lines_count = File.read('app/models/application_record.rb').lines.count
57
79
 
@@ -103,7 +103,7 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
103
103
  end
104
104
 
105
105
  def generate_basic_mutations(resource)
106
- system("mkdir -p #{@mutations_directory}")
106
+ FileUtils.mkdir_p(@mutations_directory) unless File.directory?(@mutations_directory)
107
107
  system("rails generate graphql_mutations #{resource}")
108
108
 
109
109
  # Graphql Input Type
@@ -126,7 +126,8 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
126
126
  end
127
127
 
128
128
  def generate_graphql_input_type(resource)
129
- system("mkdir -p #{@mutations_directory}")
129
+ FileUtils.mkdir_p(@mutations_directory) unless File.directory?(@mutations_directory)
130
+
130
131
  File.write(
131
132
  "#{@mutations_directory}/input_type.rb",
132
133
  <<~STRING
@@ -241,6 +242,9 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
241
242
  end
242
243
 
243
244
  def generate_service(resource)
245
+
246
+ FileUtils.mkdir_p("app/graphql/#{resource.pluralize}/") unless File.directory?("app/graphql/#{resource.pluralize}/")
247
+
244
248
  File.write(
245
249
  "app/graphql/#{resource.pluralize}/service.rb",
246
250
  <<~STRING
@@ -308,13 +312,13 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
308
312
  end
309
313
 
310
314
  def add_to_model(model, line)
311
- file_name = "app/models/#{model.underscore.singularize}.rb"
315
+ file_name = File.join("app","models","#{model.underscore.singularize}.rb")
312
316
  return if !File.exist?(file_name) || File.read(file_name).include?(line)
313
317
 
314
- line_count = `wc -l "#{file_name}"`.strip.split(' ')[0].to_i
315
-
318
+ file = open(file_name)
319
+ line_count = file.readlines.size
316
320
  line_nb = 0
317
- File.open(file_name).each do |l|
321
+ file.each do |l|
318
322
  line_nb += 1
319
323
  break if l.include?('ApplicationRecord')
320
324
  end
@@ -4,37 +4,110 @@ require 'rkelly'
4
4
  module Graphql
5
5
  class HydrateQuery
6
6
 
7
- def initialize(model, context, order_by: nil, filter: nil, id: nil, user: nil, page: nil, per_page: 10)
7
+ def initialize(model, context, order_by: nil, filter: nil, check_visibility: true, id: nil, user: nil, page: nil, per_page: nil)
8
8
  @context = context
9
9
  @filter = filter
10
10
  @order_by = order_by
11
11
  @model = model
12
12
  @models = [model_name.singularize.camelize]
13
+ @check_visibility = check_visibility
13
14
  @id = id
14
15
  @user = user
15
- @page = page
16
- @per_page = per_page
16
+ @page = page || 1
17
+ @per_page = per_page || 1000
17
18
  end
18
19
 
19
20
  def run
20
- @model = @model.where(transform_filter(@filter)) if @filter
21
- @model = @model.order(@order_by) if @order_by
22
-
23
- @model = @model.limit(@per_page) if @per_page
24
- @model = @model.offset(@per_page * (@page - 1)) if @page
25
-
26
- @model = @model.where(id: @id) if @id
27
- plucked = DeepPluck::Model.new(@model.visible_for(user: @user), user: @user).add(
28
- hash_to_array_of_hashes(parse_fields(@context&.irep_node), @model)
29
- ).load_all
30
- result = plucked_attr_to_structs(plucked, model_name.singularize.camelize.constantize)&.compact
31
- @id ? result.first : result
21
+ if @id
22
+ @model = @model.where(id: @id)
23
+ deep_pluck_to_structs(@context&.irep_node).first
24
+ else
25
+ @model = @model.limit(@per_page)
26
+ @model = @model.offset(@per_page * (@page - 1))
27
+ filter_and_order
28
+ deep_pluck_to_structs(@context&.irep_node)
29
+ end
30
+ end
31
+
32
+ def paginated_run
33
+ filter_and_order
34
+
35
+ @total = @model.length
36
+ @model = @model.limit(@per_page)
37
+ @model = @model.offset(@per_page * (@page - 1))
38
+
39
+ ::Rails.logger.info(@model.to_sql)
40
+ OpenStruct.new(
41
+ data: deep_pluck_to_structs(@context&.irep_node&.typed_children&.values&.first.try(:[], 'data')),
42
+ total_count: @total,
43
+ per_page: @per_page,
44
+ page: @page
45
+ )
46
+ end
47
+
48
+ private
49
+
50
+ def filter_and_order
51
+ if @filter
52
+ transformed_filter = transform_filter(@filter)
53
+ to_join = transformed_filter.split(/AND|OR|like|ilike/).map do |expression|
54
+ expression.strip.split(/!=|=|IS/).first.strip
55
+ end.select { |e| e.include?('.') }.map { |e| e.split('.').first }.map(&:to_sym)
56
+ to_join.reject { |j| j.to_s.pluralize.to_sym == @model.klass.to_s.pluralize.underscore.to_sym }.each do |j|
57
+ @model = @model.left_joins(j).distinct
58
+ end
59
+ transformed_filter = transformed_filter.split(/(AND|OR|like|ilike)/).map do |e|
60
+ arr = e.split(/(!=|=|IS)/)
61
+ if arr.first.include?('.')
62
+ arr.first.split('.').first.pluralize + '.' + arr.first.split('.').last + arr[1].to_s + arr[2].to_s
63
+ else
64
+ arr.join
65
+ end
66
+ end.join
67
+ @model = @model.where(transformed_filter)
68
+ end
69
+
70
+ return unless @order_by
71
+
72
+ sign = @order_by.split(' ').last.downcase == 'desc' ? 'desc' : 'asc'
73
+ column = @order_by.split(' ').first
74
+ if column.include?('.')
75
+ @model = @model.left_joins(column.split('.').first.to_sym)
76
+ string_type = %i[string text].include?(
77
+ evaluate_model(@model, column.split('.').first).columns_hash[column.split('.').last]&.type
78
+ )
79
+
80
+ @to_select_to_add = if string_type
81
+ "upper(#{column.split('.').first.pluralize}.#{column.split('.').last})"
82
+ else
83
+ column.split('.').first.pluralize + '.' + column.split('.').last
84
+ end
85
+ @model = @model.select(@to_select_to_add)
86
+ column = "#{column.split('.').first.pluralize}.#{column.split('.').last}"
87
+ @model = @model.order(Arel.sql("#{string_type ? "upper(#{column})" : column} #{sign}"))
88
+ elsif @order_by
89
+ column = "upper(#{model_name}.#{column})" if %i[string text].include?(@model.columns_hash[column]&.type)
90
+ @model = @model.order("#{column} #{sign}")
91
+ end
32
92
  end
33
93
 
34
94
  def transform_filter(filter)
35
- parsed_filter = RKelly::Parser.new.parse(filter.gsub('like', ' | ')).to_ecma
36
- parsed_filter.gsub(' | ', ' like ').
37
- gsub('||', 'OR').gsub('&&', 'AND').gsub('===', '=').gsub('==', '=').delete(';')
95
+ parsed_filter = RKelly::Parser.new.parse(filter.gsub('like', ' | '))&.to_ecma
96
+ return '' unless parsed_filter
97
+
98
+ @model.klass.defined_enums.values.reduce(:merge)&.each { |k, v| parsed_filter.gsub!("= #{k}", "= #{v}") }
99
+ parsed_filter.gsub(' | ', ' ilike ').gsub('||', 'OR').gsub('&&', 'AND').gsub('===', '=').gsub('==', '=').gsub(
100
+ '!= null', 'IS NOT NULL'
101
+ ).gsub('= null', 'IS NULL').delete(';')
102
+ end
103
+
104
+ def deep_pluck_to_structs(irep_node)
105
+ plucked_attr_to_structs(
106
+ DeepPluck::Model.new(@model.visible_for(user: @user), user: @user).add(
107
+ ((hash_to_array_of_hashes(parse_fields(irep_node), @model) || []) + [@to_select_to_add]).compact
108
+ ).load_all,
109
+ model_name.singularize.camelize.constantize
110
+ )&.compact
38
111
  end
39
112
 
40
113
  def plucked_attr_to_structs(arr, parent_model)
@@ -104,9 +177,7 @@ module Graphql
104
177
 
105
178
  def parse_fields(irep_node)
106
179
  fields = irep_node&.scoped_children&.values&.first
107
- if fields.key?('edges')
108
- fields = fields['edges'].scoped_children.values.first['node']&.scoped_children&.values&.first
109
- end
180
+ fields = fields['edges'].scoped_children.values.first['node']&.scoped_children&.values&.first if fields&.key?('edges')
110
181
  return if fields.blank?
111
182
 
112
183
  fields.each_with_object({}) do |(k, v), h|
@@ -1,7 +1,7 @@
1
1
  module Graphql
2
2
  module Rails
3
3
  module Api
4
- VERSION = '0.7.5'.freeze
4
+ VERSION = '0.9.1'.freeze
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-rails-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - poilon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-28 00:00:00.000000000 Z
11
+ date: 2022-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -44,20 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 6.0.0
47
+ version: 6.1.4
48
48
  - - "~>"
49
49
  - !ruby/object:Gem::Version
50
- version: 6.0.0
50
+ version: 7.0.0
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: 6.0.0
57
+ version: 6.1.4
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 6.0.0
60
+ version: 7.0.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rkelly-remix
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubygems_version: 3.0.6
117
+ rubygems_version: 3.0.8
118
118
  signing_key:
119
119
  specification_version: 4
120
120
  summary: Graphql rails api framework to create easily graphql api with rails