hai 0.0.3 → 0.0.5
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 +4 -4
- data/README.md +16 -4
- data/app/controllers/hai/rest_controller.rb +4 -0
- data/lib/generators/install/graphql_generator.rb +61 -0
- data/lib/generators/rest/install_generator.rb +14 -0
- data/lib/hai/create.rb +1 -1
- data/lib/hai/graphql/create_mutations.rb +16 -2
- data/lib/hai/graphql/types.rb +3 -2
- data/lib/hai/graphql.rb +13 -7
- data/lib/hai/read.rb +2 -2
- data/lib/hai/restricted_attributes.rb +17 -0
- data/lib/hai/version.rb +1 -1
- data/lib/hai.rb +4 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 398bd31884dbdd9428de5a190d7266098c5ffbe0516e9d46587c6986097d3626
|
4
|
+
data.tar.gz: 5f1a60c718f37fdae163f36b8575c36826f0fe511410e6981d7ca48d4f2c0256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
data/lib/hai/create.rb
CHANGED
@@ -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:
|
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
|
+
|
data/lib/hai/graphql/types.rb
CHANGED
@@ -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
|
-
|
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(
|
37
|
-
|
38
|
-
|
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(
|
42
|
-
|
43
|
-
|
44
|
-
|
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
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
|
-
|
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.
|
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-
|
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
|