hai 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd1e9a5e790765b1b2030e4384048a2ad08f420e2078b5d883e2bffd2d8dc8eb
4
- data.tar.gz: 4da9e653d8c708d2e01135aa8cbf70234ec73100a0c158cb3dbd1583a47add28
3
+ metadata.gz: 398bd31884dbdd9428de5a190d7266098c5ffbe0516e9d46587c6986097d3626
4
+ data.tar.gz: 5f1a60c718f37fdae163f36b8575c36826f0fe511410e6981d7ca48d4f2c0256
5
5
  SHA512:
6
- metadata.gz: dda8bcf71ee7a008b7fac3c6ad0f83b25e3d4fb3c50078b7cae6e1d9d896fa1d3d88b18eacced38fe7ce2e7e6c1efd55c02dc6187934376ab03e7f28f7ed7af4
7
- data.tar.gz: f125a58684eeba263730397623dd1f3fa58b1168423960c88cb5a0d4f815f6312c18d470d558c8cb8f9a992d542b60637c2086dd4487b0b8737ea48db0c19015
6
+ metadata.gz: 4db91d3fccbeec97c69aaee403a9d861f4a7ab5837f66279e0102041ae51d58505bc21f9bfebd26b148c2ae41de1c8b53479885bd73eb1297995a437683ebb2d
7
+ data.tar.gz: f6468efb72bdbf3c1e04f00de6778ba43b4bbf839f1c17bec32eee0918fc2ac23049ef2c4579fff6c8827fbbfb761596430310e0a1243b0fea3437d7fbbf6ab3
data/README.md CHANGED
@@ -21,7 +21,8 @@ And then execute:
21
21
 
22
22
  Hai is a resource based api and those resources are ActiveRecord models. Keeping with this first principle, let's see how it can be used in your Ruby application.
23
23
 
24
- ## Action Modifications
24
+ <details>
25
+ <summary>Action Modifications </summary>
25
26
 
26
27
  If you want to modify any of the actions, you can add a Actions module to the
27
28
  model that you want to modify.
@@ -49,7 +50,10 @@ class Post < ApplicationRecord
49
50
  end
50
51
  end
51
52
  ```
52
- ## Policies
53
+ </details>
54
+
55
+ <details>
56
+ <summary> Policies</summary>
53
57
  Policies are handled in the same manner of Action Modifications. We will use the `Policies` module in the model to handle things like authorization.
54
58
 
55
59
  ```ruby
@@ -84,8 +88,10 @@ class Post < ApplicationRecord
84
88
  end
85
89
  end
86
90
  ```
91
+ </details>
87
92
 
88
- ## Graphql
93
+ <details>
94
+ <summary>Graphql</summary>
89
95
 
90
96
  Hai Graphql depends on `graphql-ruby` so if you don't have that installed and
91
97
  boostrapped, head over to [ their repo and do that now ](https://github.com/rmosolgo/graphql-ruby#installation).
@@ -128,8 +134,11 @@ module Types
128
134
  end
129
135
  end
130
136
  ```
137
+ </details>
138
+
139
+ <details>
131
140
 
132
- ## Rest
141
+ <summary>Rest</summary>
133
142
 
134
143
  This is even easier than adding Hai Graphql. Hai Rest is a dynamic engine that can be mounted with any namespace. You just have to mount it in your routes file like this:
135
144
 
@@ -192,6 +201,9 @@ Or all things combined
192
201
  #### Delete a user
193
202
  `DELETE <base_url>/rest/users/1`
194
203
 
204
+ </details>
205
+
206
+
195
207
  ## Development
196
208
 
197
209
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
@@ -53,6 +53,10 @@ module Hai
53
53
 
54
54
  private
55
55
 
56
+ def context
57
+ try(:super) || {}
58
+ end
59
+
56
60
  def model_class
57
61
  params[:model].classify.constantize
58
62
  end
@@ -0,0 +1,61 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/base'
3
+
4
+ module Hai
5
+ module Install
6
+ class GraphqlGenerator < Rails::Generators::Base
7
+ def rails_preload
8
+ Rails.application.eager_load!
9
+ end
10
+
11
+ def install_graphql_ruby
12
+ gem 'graphql'
13
+ run "bundle install"
14
+ run "rails generate graphql:install"
15
+ end
16
+
17
+ def add_types
18
+ hai_types = "hay_types(#{model_names.join(', ')})"
19
+ inject_into_file "app/graphql/#{app_name.underscore}_schema.rb", after: "class #{app_name}Schema < GraphQL::Schema" do <<~RUBY.indent(4)
20
+
21
+ include Hai::GraphQL::Types
22
+ hai_types(#{model_names.join(', ')})
23
+ RUBY
24
+ end
25
+ end
26
+
27
+ def add_queries
28
+ inject_into_file "app/graphql/types/query_type.rb", after: "include GraphQL::Types::Relay::HasNodesField" do <<~RUBY.indent(4)
29
+
30
+ include Hai::GraphQL
31
+ hai_query(#{model_names.join(', ')})
32
+ RUBY
33
+ end
34
+ end
35
+
36
+ def add_mutations
37
+ inject_into_file "app/graphql/types/mutation_type.rb", after: "class MutationType < Types::BaseObject" do <<~RUBY.indent(4)
38
+
39
+ include Hai::GraphQL
40
+ hai_mutation(#{model_names.join(', ')})
41
+ RUBY
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def model_names
48
+ ApplicationRecord.descendants.map(&:name)
49
+ end
50
+
51
+ def app_name
52
+ require File.expand_path("config/application", destination_root)
53
+ if Rails.application.class.respond_to?(:module_parent_name)
54
+ Rails.application.class.module_parent_name
55
+ else
56
+ Rails.application.class.parent_name
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/base'
3
+
4
+ module Hai
5
+ module Rest
6
+ class InstallGenerator < Rails::Generators::Base
7
+ def mount_engine
8
+ route <<-RUBY
9
+ mount Hai::Rest::Engine => "/rest"
10
+ RUBY
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/hai/create.rb CHANGED
@@ -14,7 +14,7 @@ module Hai
14
14
 
15
15
  return unauthorized_error unless check_policy(instance)
16
16
 
17
- instance.assign_attributes(**attrs)
17
+ instance.assign_attributes(**attrs) unless attrs.empty?
18
18
 
19
19
  run_action_modification(instance)
20
20
 
@@ -15,18 +15,21 @@ module Hai
15
15
  klass.description("Attributes for creating or updating a #{model}.")
16
16
  model.attribute_types.each do |attr, type|
17
17
  next if %w[id created_at updated_at].include?(attr)
18
+ next if attr.blank? # if the model has no other attributes
19
+
20
+ presence_validators = get_presence_validators(model)
18
21
 
19
22
  klass.argument(
20
23
  attr,
21
24
  Hai::GraphQL::TYPE_CAST[type.class] ||
22
25
  Hai::GraphQL::TYPE_CAST[type.class.superclass],
23
- required: false
26
+ required: presence_validators.include?(attr),
24
27
  )
25
28
  end
26
29
 
27
30
  klass.field(:result, ::Types.const_get("#{model}Type"))
28
31
 
29
- klass.define_method(:resolve) do |args|
32
+ klass.define_method(:resolve) do |args = {}|
30
33
  Hai::Create.new(model, context).execute(**args)
31
34
  end
32
35
  Hai::GraphQL::Types.const_set("Create#{model}", klass)
@@ -38,7 +41,18 @@ module Hai
38
41
  mutation: Hai::GraphQL::Types.const_get("Create#{model}")
39
42
  )
40
43
  end
44
+
45
+ private
46
+
47
+ def get_presence_validators(model)
48
+ model.validators.select do |v|
49
+ v.kind == :presence
50
+ end
51
+ .flat_map(&:attributes)
52
+ .map(&:to_s)
53
+ end
41
54
  end
42
55
  end
43
56
  end
44
57
  end
58
+
@@ -45,7 +45,8 @@ module Hai
45
45
 
46
46
  klass = Class.new(::Types::BaseObject)
47
47
  model.attribute_types.each do |attr, type|
48
- klass.send(:field, attr, Hai::GraphQL::TYPE_CAST[type.class])
48
+ next if defined?(model.get_restricted_attributes) && model.get_restricted_attributes.include?(attr.to_sym) # add test plz
49
+ klass.send(:field, attr, Hai::GraphQL::TYPE_CAST[type.class] || Hai::GraphQL::TYPE_CAST[type.class.superclass])
49
50
  rescue ArgumentError => e
50
51
  binding.pry
51
52
  end
@@ -80,7 +81,7 @@ module Hai
80
81
 
81
82
  klass.argument(
82
83
  attr,
83
- Hai::GraphQL::TYPE_CAST[type.class],
84
+ Hai::GraphQL::TYPE_CAST[type.class]|| Hai::GraphQL::TYPE_CAST[type.class.superclass],
84
85
  required: false
85
86
  )
86
87
  end
data/lib/hai/graphql.rb CHANGED
@@ -15,6 +15,7 @@ module Hai
15
15
  ActiveModel::Type::Integer => ::GraphQL::Types::Int,
16
16
  ActiveModel::Type::Float => ::GraphQL::Types::Float,
17
17
  ActiveModel::Type::String => ::GraphQL::Types::String,
18
+ ActiveRecord::Type::Text => ::GraphQL::Types::String,
18
19
  ActiveModel::Type::Boolean => ::GraphQL::Types::Boolean,
19
20
  ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter =>
20
21
  ::GraphQL::Types::ISO8601DateTime
@@ -23,6 +24,7 @@ module Hai
23
24
  ActiveModel::Type::Integer => Hai::GraphQL::Types::Arel::IntInputType,
24
25
  ActiveModel::Type::Float => Hai::GraphQL::Types::Arel::FloatInputType,
25
26
  ActiveModel::Type::String => Hai::GraphQL::Types::Arel::StringInputType,
27
+ ActiveRecord::Type::Text => Hai::GraphQL::Types::Arel::StringInputType,
26
28
  ActiveModel::Type::Boolean => Hai::GraphQL::Types::Arel::BooleanInputType,
27
29
  ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter =>
28
30
  Hai::GraphQL::Types::Arel::DateTimeInputType
@@ -33,15 +35,19 @@ module Hai
33
35
  end
34
36
 
35
37
  module ClassMethods
36
- def hai_query(model)
37
- Hai::GraphQL::ReadQueries.add(self, model)
38
- Hai::GraphQL::ListQueries.add(self, model)
38
+ def hai_query(*models)
39
+ models.each do |model|
40
+ Hai::GraphQL::ReadQueries.add(self, model)
41
+ Hai::GraphQL::ListQueries.add(self, model)
42
+ end
39
43
  end
40
44
 
41
- def hai_mutation(model)
42
- Hai::GraphQL::CreateMutations.add(self, model)
43
- Hai::GraphQL::UpdateMutations.add(self, model)
44
- Hai::GraphQL::DeleteMutations.add(self, model)
45
+ def hai_mutation(*models)
46
+ models.each do |model|
47
+ Hai::GraphQL::CreateMutations.add(self, model)
48
+ Hai::GraphQL::UpdateMutations.add(self, model)
49
+ Hai::GraphQL::DeleteMutations.add(self, model)
50
+ end
45
51
  end
46
52
  end
47
53
  end
data/lib/hai/read.rb CHANGED
@@ -34,7 +34,7 @@ module Hai
34
34
 
35
35
  private
36
36
 
37
- def check_read_policy
37
+ def check_read_policy(context)
38
38
  if model.const_defined?("Policies") && model::Policies.respond_to?(:read)
39
39
  model::Policies.read(context)
40
40
  else
@@ -42,7 +42,7 @@ module Hai
42
42
  end
43
43
  end
44
44
 
45
- def check_list_policy
45
+ def check_list_policy(context)
46
46
  if model.const_defined?("Policies") && model::Policies.respond_to?(:list)
47
47
  model::Policies.list(context)
48
48
  else
@@ -0,0 +1,17 @@
1
+ module Hai
2
+ module RestrictedAttributes
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def restricted_attributes(*attrs)
9
+ @@restricted_attributes = attrs
10
+ end
11
+
12
+ def get_restricted_attributes
13
+ @@restricted_attributes
14
+ end
15
+ end
16
+ end
17
+ end
data/lib/hai/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hai
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.5"
5
5
  end
data/lib/hai.rb CHANGED
@@ -12,15 +12,18 @@ require_relative "hai/read"
12
12
  require_relative "hai/create"
13
13
  require_relative "hai/update"
14
14
  require_relative "hai/delete"
15
+ require_relative "hai/restricted_attributes"
15
16
 
16
17
  require_relative "hai/policies"
17
18
  require_relative "hai/action_mods"
18
19
  require "hai/railtie" if defined?(Rails)
20
+ require "generators/rest/install_generator" if defined?(Rails)
21
+ require "generators/install/graphql_generator" if defined?(Rails)
19
22
 
20
23
  module Hai
21
24
  class Error < StandardError
22
25
  end
23
- class Rest
26
+ module Rest
24
27
  class Engine < ::Rails::Engine
25
28
  isolate_namespace Hai
26
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - basicbrogrammer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-02-07 00:00:00.000000000 Z
11
+ date: 2023-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -82,6 +82,8 @@ files:
82
82
  - Rakefile
83
83
  - app/controllers/hai/rest_controller.rb
84
84
  - config/routes.rb
85
+ - lib/generators/install/graphql_generator.rb
86
+ - lib/generators/rest/install_generator.rb
85
87
  - lib/hai.rb
86
88
  - lib/hai/action_mods.rb
87
89
  - lib/hai/create.rb
@@ -97,6 +99,7 @@ files:
97
99
  - lib/hai/policies.rb
98
100
  - lib/hai/railtie.rb
99
101
  - lib/hai/read.rb
102
+ - lib/hai/restricted_attributes.rb
100
103
  - lib/hai/tasks/graphql/filter_type.rake
101
104
  - lib/hai/tasks/hai.rake
102
105
  - lib/hai/types/arel/boolean_input_type.rb