ralphql_generator 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 424c0525b6ba37043784f664352284c95a761e514567097a1078e5a9a62f68ce
4
+ data.tar.gz: b6f2c7930183531db5d6d7d674d346eb850e0ee1b7dc028daca13f5d75092db0
5
+ SHA512:
6
+ metadata.gz: 419ccaca078fd4e800ada37e6d7a92aa9462a11c2e26d42b7a1aacee9c19f10e6a4e4ae223f26bcd8e7b1aa243ab529aed7af379f8db458d7d4855d26a77b135
7
+ data.tar.gz: c2384bd3f947cde30351f00f005257b281baf7bdc84cd20d43fd4fce8b7aea5bc61fabcffb37a016a7a2013e768fde89f0facc225374b0d583eaeac1cea21978
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Ralphql_generator
2
+
3
+ ralphql_generator an useful gem for generating GraphQL queries and mutations in Rails applications. With ralphql_generator, you can quickly and easily create queries and mutations based on your application's data model, freeing up your time to focus on more complex development tasks.
4
+
5
+ By using ralphql_generator, you can reduce the likelihood of typos and other errors that can occur when writing GraphQL queries and mutations by hand. Instead, you can generate the necessary code with a few simple commands and then customize it as needed to fit your specific requirements.
6
+
7
+ ralphql_generator's name is a playful reference to the lovable yet dimwitted character from The Simpsons, Ralph Wiggum. By leaving the simple tasks to Ralph, you can focus on the parts of your application that truly require your expertise and creativity.
8
+
9
+ ![ralph computing](https://media.giphy.com/media/xT5LMI5WLGkftxKJeE/giphy.gif)
10
+
11
+ ## Installation
12
+ Add this line to your application's Gemfile:
13
+ ```ruby
14
+ gem 'ralphql_generator'
15
+ ```
16
+ And then execute:
17
+ ```bash
18
+ $ bundle install
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```bash
24
+ $ gem install ralphql_generator
25
+ ```
26
+
27
+ ## Usage
28
+ ### Queries Generators
29
+ ```bash
30
+ $ rails generate gql YourModel
31
+ ```
32
+ And it will create base files:
33
+ - `app/graphql/types/your_model_type.rb`
34
+ - `app/graphql/resolvers/your_model_resolver.rb`
35
+ - `app/policies/your_model_policy.rb`
36
+ - `spec/fixtures/graphql/your_models.graphql`
37
+ - `spec/graphql/queries/your_models_spec.rb`
38
+ and it add `your_models_field` into `app/graphql/types/query_type.rb`
39
+
40
+ Then now you just have to update `your_model_policy.rb` and update or remove `xit` in `your_models_spec.rb` to have a base type fetchable
41
+
42
+ ### Mutations Generators
43
+ ```bash
44
+ $ rails generate gql_mutation YourMutation
45
+ ```
46
+ And it will create base files:
47
+ - `app/graphql/mutations/your_mutation.rb`
48
+ - `spec/graphql/mutations/your_mutation_spec.rb`
49
+ - `spec/fixtures/graphql/mutations/your_mutations.graphql`
50
+ There is no magical here, juste generate base files, you have to create your own business logic inside
51
+
52
+ ## Development
53
+
54
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
55
+
56
+
57
+
58
+ ## Contributing
59
+ ## License
60
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
61
+
62
+ ## Code of Conduct
63
+
64
+ Everyone interacting in the ralphql_generator project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/tymate/ralphql_generator/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ bin/rails generate gql Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GqlGenerator < Rails::Generators::NamedBase
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ def create_gql_file
7
+ template 'exemple_policy.rb', File.join('app/policies/', "#{file_name.underscore}_policy.rb")
8
+ template 'exemple_spec.rb', File.join('spec/graphql/queries', "#{file_name.underscore.pluralize}_spec.rb")
9
+ template 'exemple_resolver.rb', File.join('app/graphql/resolvers', "#{file_name.underscore}_resolver.rb")
10
+ template 'exemple.graphql.rb', File.join('spec/fixtures/graphql', "#{file_name.underscore.pluralize}.graphql")
11
+ template 'exemple_type.rb', File.join('app/graphql/types', "#{file_name.underscore}_type.rb")
12
+ insert_into_query_type
13
+ end
14
+
15
+ private # Example method that can be invoked from the template
16
+
17
+ def excluded_columns
18
+ %i[id created_at updated_at]
19
+ end
20
+
21
+ def base_order_columns
22
+ %i[created_at updated_at position]
23
+ end
24
+
25
+ def insert_into_query_type
26
+ inject_into_file 'app/graphql/types/query_type.rb', after: "# Index Queries\n" do
27
+ " field :#{file_name.underscore.pluralize},
28
+ Types:: #{class_name.constantize}Type.connection_type,
29
+ resolver: Resolvers::#{class_name.constantize}Resolver,
30
+ preauthorize: { to: :index?, with: #{class_name.constantize}Policy },
31
+ connection: GraphQL::Connections::Stable,
32
+ null: false\n"
33
+ end
34
+ end
35
+
36
+ def graphqlTypeFor(type)
37
+ types = {
38
+ string: 'String',
39
+ text: 'String',
40
+ integer: 'Int',
41
+ float: 'Float',
42
+ boolean: 'Boolean',
43
+ datetime: 'GraphQL::Types::ISO8601DateTime',
44
+ date: 'GraphQL::Types::ISO8601Date',
45
+ json: 'JSON'
46
+ }
47
+ types[type]
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ query <%= class_name.camelize(:lower).pluralize %>{
2
+ <%= class_name.camelize(:lower).pluralize %>{
3
+ nodes{
4
+ <%- class_name.constantize.columns.each do |column| -%>
5
+ <%- next if class_name.constantize.reflect_on_all_associations.map(&:foreign_key).include?(column.name) -%>
6
+ <%= column.name.camelize(:lower)%>
7
+ <%- end -%>
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= class_name %>Policy < ApplicationPolicy
4
+ relation_scope do |scope|
5
+ raise "Add custom policy scope in #{__FILE__}"
6
+ end
7
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resolvers
4
+ class <%= class_name %>Resolver < BaseResolver
5
+ include SearchObject.module(:graphql)
6
+
7
+ description 'Search resolver for <%= class_name.underscore %>'
8
+
9
+ type Types::<%= class_name %>Type.connection_type, null: false
10
+
11
+ scope do
12
+ authorized_scope(<%= class_name %>.all)
13
+ end
14
+
15
+ class OrderColumnEnum < Types::BaseEnum
16
+ description 'Available columns for ordering'
17
+
18
+ graphql_name '<%= class_name %>OrderColumn'
19
+
20
+ <%- class_name.constantize.columns.each do |column| -%>
21
+ <%- next unless base_order_columns.include?(column.name.to_sym) -%>
22
+ value '<%= column.name.to_sym.upcase %>', value: :<%= column.name %>
23
+ <%- end -%>
24
+ end
25
+
26
+ class <%= class_name %>OrderCriteria < Types::BaseInputObject
27
+ description 'Criteria for ordering'
28
+
29
+ argument :column, OrderColumnEnum, required: true
30
+ argument :direction, Types::OrderDirectionType, required: true
31
+ end
32
+
33
+ DEFAULT_ORDER = { column: :created_at, direction: :asc }.freeze
34
+
35
+ option(
36
+ :order,
37
+ type: <%= class_name %>OrderCriteria, default: DEFAULT_ORDER
38
+ ) do |scope, order|
39
+ scope.order(order.column => order.direction)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Types::QueryType, type: :request do
6
+
7
+ let(:query) { '<%= class_name.camelize(:lower).pluralize %>' }
8
+ let(:data) { json.dig(:data, :<%= class_name.camelize(:lower).pluralize %>, :nodes) }
9
+
10
+ describe '<%= class_name.underscore %>' do
11
+ it_behaves_like 'with standard user' do
12
+ before do
13
+ 5.times do
14
+ Fabricate(:<%= class_name.underscore %>)
15
+ end
16
+ do_graphql_request
17
+ end
18
+
19
+ it 'get a <%= class_name.underscore.pluralize %> list' do
20
+ raise "Change me or adopt me in #{__FILE__}"
21
+ expect(errors).to be_blank
22
+ expect(data.size).to eq(5)
23
+ end
24
+ end
25
+ end
26
+
27
+ describe 'when unauthenticated' do
28
+ before do
29
+ do_graphql_request
30
+ end
31
+
32
+ include_examples 'when unauthenticated'
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Types
4
+ class <%= class_name %>Type < Types::BaseType
5
+ description 'A <%= class_name %>'
6
+
7
+ <%- class_name.constantize.columns.each do |column| -%>
8
+ <%- next if excluded_columns.include?(column.name.to_sym) || class_name.constantize.reflect_on_all_associations.map(&:foreign_key).include?(column.name) -%>
9
+ field :<%= column.name %>, <%= graphqlTypeFor(column.type) %>, null: <%= column.null %>
10
+ <%- end -%>
11
+ # belongs_to Associations
12
+ <%- class_name.constantize.reflect_on_all_associations(:belongs_to).each do |association| -%>
13
+ field :<%= association.name %>, Types::<%= association.klass.name %>Type, null: false
14
+ <%- end -%>
15
+ # has_many Associations
16
+ <%- class_name.constantize.reflect_on_all_associations(:has_many).each do |association| -%>
17
+ field :<%= association.name %>, Types::<%= association.klass.name %>Type.connection_type, resolver: Resolvers::<%= association.klass.name %>Resolver, null: true
18
+ <%- end -%>
19
+ # has_one Associations
20
+ <%- class_name.constantize.reflect_on_all_associations(:has_one).each do |association| -%>
21
+ <%- if association.options[:class_name] == "ActionText::RichText" -%>
22
+ field :<%= association.name %>, String, null: true
23
+ <%- else -%>
24
+ field :<%= association.name %>, Types::<%= association.klass.name %>Type, null: true
25
+ <%- end -%>
26
+ <%- end -%>
27
+ end
28
+ end
29
+
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ bin/rails generate gql_mutation Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,18 @@
1
+ class GqlMutationGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path("templates", __dir__)
3
+
4
+ def create_gql_file
5
+ template 'exemple_mutation.rb', File.join('app/graphql/mutations', "#{file_name.underscore}.rb")
6
+ template 'exemple_mutation_spec.rb', File.join('spec/graphql/mutations', "#{file_name.underscore}_spec.rb")
7
+ template 'exemple_mutation.graphql.rb', File.join('spec/fixtures/graphql/mutations/', "#{file_name.underscore}s.graphql")
8
+ update_mutation_type
9
+ end
10
+
11
+ private
12
+
13
+ def update_mutation_type
14
+ path = 'app/graphql/types/mutation_type.rb'
15
+ mutations = File.read(path).gsub("end\nend\n", " field :#{file_name.underscore}, mutation: Mutations::#{file_name.camelize}\n end\nend\n")
16
+ File.write(path, mutations)
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ fragment errorFields on ValidationError {
2
+ path
3
+ message
4
+ attributes
5
+ error
6
+ }
7
+
8
+ mutation <%= class_name.camelize(:lower) %>($input: <%= class_name.camelize %>Input!) {
9
+ <%= class_name.camelize(:lower) %>(input: $input) {
10
+ changeMe {
11
+ id
12
+ }
13
+ errors {
14
+ ...errorFields
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutations
4
+ class <%= class_name %> < BaseMutation
5
+ description '<%= class_name %>'
6
+
7
+ # argument :argument_name, String, required: false
8
+ # field :field_name, Types::MyType, null: true
9
+
10
+ def resolve(**args)
11
+ # authorize! current_user, to: :<%= class_name.underscore %>?
12
+ # todo add logic here
13
+ # {field_name: field_name}
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Mutations::<%= class_name %>, type: :request do
6
+ let(:query) { '<%= class_name.camelize(:lower) %>' }
7
+
8
+ # let(:object) { Fabricate :object }
9
+
10
+ let(:variables) do
11
+ {
12
+ input: {
13
+ # objectId: object.to_sgid.to_s
14
+ }
15
+ }
16
+ end
17
+
18
+ it_behaves_like 'with standard user' do
19
+ xit '<%= class_name %>' do
20
+ do_graphql_request
21
+ expect(errors).to be_blank
22
+ data = json.dig('data', '<%= class_name.camelize(:lower) %>', 'object').deep_symbolize_keys
23
+ expect(data).not_to be_empty
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Ralphql
2
+ VERSION = "0.2.0"
3
+ end
data/lib/ralphql.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "ralphql/version"
2
+
3
+ module Ralphql
4
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ralphql_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Michel Delpierre
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 7.0.4.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '7.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 7.0.4.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: puma
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ description: ''
48
+ email:
49
+ - tech@tymate.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - README.md
55
+ - Rakefile
56
+ - lib/generators/gql/USAGE
57
+ - lib/generators/gql/gql_generator.rb
58
+ - lib/generators/gql/templates/exemple.graphql.rb
59
+ - lib/generators/gql/templates/exemple_policy.rb
60
+ - lib/generators/gql/templates/exemple_resolver.rb
61
+ - lib/generators/gql/templates/exemple_spec.rb
62
+ - lib/generators/gql/templates/exemple_type.rb
63
+ - lib/generators/gql_mutation/USAGE
64
+ - lib/generators/gql_mutation/gql_mutation_generator.rb
65
+ - lib/generators/gql_mutation/templates/exemple_mutation.graphql.rb
66
+ - lib/generators/gql_mutation/templates/exemple_mutation.rb
67
+ - lib/generators/gql_mutation/templates/exemple_mutation_spec.rb
68
+ - lib/ralphql.rb
69
+ - lib/ralphql/version.rb
70
+ homepage: https://rubygems.org/gems/ralph_ql
71
+ licenses:
72
+ - MIT
73
+ metadata:
74
+ homepage_uri: https://rubygems.org/gems/ralph_ql
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubygems_version: 3.0.3.1
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: A Ruby on Rails gralphql generators
94
+ test_files: []