grape_on_rails 1.0.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 +7 -0
- data/.gitignore +186 -0
- data/.rubocop.yml +530 -0
- data/.rubocop_disabled.yml +153 -0
- data/.rubocop_enabled.yml +756 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +41 -0
- data/LICENSE.txt +21 -0
- data/README.md +45 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/grape_on_rails.gemspec +33 -0
- data/lib/grape_on_rails.rb +78 -0
- data/lib/grape_on_rails/api.rb +36 -0
- data/lib/grape_on_rails/api_error.rb +19 -0
- data/lib/grape_on_rails/attributes.rb +52 -0
- data/lib/grape_on_rails/authenticator.rb +24 -0
- data/lib/grape_on_rails/error_formatter.rb +10 -0
- data/lib/grape_on_rails/integrations/railtie.rb +38 -0
- data/lib/grape_on_rails/macros.rb +21 -0
- data/lib/grape_on_rails/models.rb +28 -0
- data/lib/grape_on_rails/models/user_actor.rb +23 -0
- data/lib/grape_on_rails/models/user_token_actor.rb +45 -0
- data/lib/grape_on_rails/secured_generator.rb +13 -0
- data/lib/grape_on_rails/sources/yaml_source.rb +21 -0
- data/lib/grape_on_rails/structural_hash.rb +48 -0
- data/lib/grape_on_rails/support.rb +14 -0
- data/lib/grape_on_rails/types/boolean.rb +21 -0
- data/lib/grape_on_rails/validator.rb +37 -0
- data/lib/grape_on_rails/version.rb +3 -0
- data/spec/grape_on_rails_spec.rb +11 -0
- data/spec/spec_helper.rb +14 -0
- metadata +200 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module GrapeOnRails
|
2
|
+
module Authenticator
|
3
|
+
include Support
|
4
|
+
|
5
|
+
attr_accessor :current_user
|
6
|
+
|
7
|
+
def authenticate!
|
8
|
+
@current_user = GoR.models.user_token.constantize
|
9
|
+
.find_token!(token_on_header)&.public_send(GoR.models.user.downcase)
|
10
|
+
raise APIError::Unauthenticated unless current_user
|
11
|
+
end
|
12
|
+
|
13
|
+
def refresh_token!
|
14
|
+
token = GoR.models.user_token.constantize.find_by refresh_token: token_on_header
|
15
|
+
token ? token.renew! : raise(APIError::Unauthenticated)
|
16
|
+
token
|
17
|
+
end
|
18
|
+
|
19
|
+
def token_on_header
|
20
|
+
auth_header = request.headers[GoR.access_token_header]
|
21
|
+
auth_header&.scan(/^#{GoR.access_token_value_prefix} (.+)$/i)&.flatten&.[]0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module GrapeOnRails
|
2
|
+
module Integrations
|
3
|
+
class Railtie < Rails::Railtie
|
4
|
+
def auto_reload_in_development
|
5
|
+
return unless ::Rails.env.development? && ::Rails::VERSION::MAJOR >= 4
|
6
|
+
reload_on_api_only_mode
|
7
|
+
reload_on_normal_mode
|
8
|
+
end
|
9
|
+
|
10
|
+
def reload_on_api_only_mode
|
11
|
+
ActionController::Base.class_eval(&reload_on_each_request)
|
12
|
+
end
|
13
|
+
|
14
|
+
def reload_on_normal_mode
|
15
|
+
ActionController::API.class_eval(&reload_on_each_request)
|
16
|
+
end
|
17
|
+
|
18
|
+
def reload_on_each_request
|
19
|
+
proc do
|
20
|
+
prepend_before_action{::GrapeOnRails.reload}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
config.before_configuration{GrapeOnRails.load}
|
25
|
+
|
26
|
+
config.after_initialize do
|
27
|
+
ActiveSupport.on_load(:active_record) do
|
28
|
+
extend GrapeOnRails::Models
|
29
|
+
end
|
30
|
+
ActiveSupport.on_load(:action_controller) do
|
31
|
+
include GrapeOnRails::API
|
32
|
+
include GrapeOnRails::Authenticator
|
33
|
+
end
|
34
|
+
auto_reload_in_development
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "grape_on_rails/attributes"
|
2
|
+
|
3
|
+
module GrapeOnRails
|
4
|
+
module Macros
|
5
|
+
include GrapeOnRails::Attributes
|
6
|
+
|
7
|
+
def requires *attrs
|
8
|
+
options = attrs.extract_options!
|
9
|
+
raise APIError::ValidationError if attrs.any?{|a| params[a].nil?}
|
10
|
+
options.each{|k, v| verify k, attrs, v}
|
11
|
+
declared_attrs attrs
|
12
|
+
end
|
13
|
+
|
14
|
+
def optional *attrs
|
15
|
+
options = attrs.extract_options!
|
16
|
+
return if attrs.any?{|a| params[a].nil?}
|
17
|
+
options.each{|k, v| verify k, attrs, v}
|
18
|
+
declared_attrs attrs
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "grape_on_rails/models/user_actor"
|
2
|
+
require "grape_on_rails/models/user_token_actor"
|
3
|
+
|
4
|
+
module GrapeOnRails
|
5
|
+
module Models
|
6
|
+
DEFAULT_USER_ACTOR = "User"
|
7
|
+
DEFAULT_USER_TOKEN_ACTOR = "UserToken"
|
8
|
+
|
9
|
+
def acts_as model
|
10
|
+
include GrapeOnRails::Models.const_get "#{model}_actor".classify
|
11
|
+
missing_columns = check_missing_columns
|
12
|
+
raise "You need to add columns: #{missing_columns} to #{name} model" unless missing_columns.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def set_default_model_actors config
|
17
|
+
config.models = StructuralHash.new.from_hash default_model_actors unless config.models
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_model_actors
|
21
|
+
{
|
22
|
+
user: DEFAULT_USER_ACTOR,
|
23
|
+
user_token: DEFAULT_USER_TOKEN_ACTOR
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module GrapeOnRails
|
2
|
+
module Models
|
3
|
+
module UserActor
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_secure_password
|
8
|
+
end
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def authenticate! email, password
|
12
|
+
find_by(email: email).tap do |user|
|
13
|
+
raise APIError::WrongEmailPassword unless user&.authenticate password
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_missing_columns
|
18
|
+
%w(email password_digest) - column_names
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module GrapeOnRails
|
2
|
+
module Models
|
3
|
+
module UserTokenActor
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Support
|
6
|
+
include SecuredGenerator
|
7
|
+
|
8
|
+
included do
|
9
|
+
has_secure_token
|
10
|
+
has_secure_token :refresh_token
|
11
|
+
|
12
|
+
def renew! remember = false
|
13
|
+
update! expires_at: GoR.token_configs.public_send(remember ? :expires_in : :short_expires_in).second.from_now,
|
14
|
+
token: unique_random(:token), refresh_token: unique_random(:refresh_token)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def expired?
|
19
|
+
expires_at <= Time.zone.now
|
20
|
+
end
|
21
|
+
|
22
|
+
def expires!
|
23
|
+
update_attributes! expired_at: Time.zone.now
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class_methods do
|
28
|
+
def generate! user
|
29
|
+
token = find_or_initialize_by GoR.models.user.downcase => user
|
30
|
+
token.renew!
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_token! token
|
34
|
+
find_by(token: token).tap do |user_token|
|
35
|
+
raise APIError::TokenExpired if user_token&.expired?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_missing_columns
|
40
|
+
%w(token refresh_token expires_at) - column_names
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module GrapeOnRails
|
2
|
+
module SecuredGenerator
|
3
|
+
def unique_random attr
|
4
|
+
str_len = GoR.token_configs
|
5
|
+
.public_send(attr)
|
6
|
+
.public_send(:secure_length).to_i / 2
|
7
|
+
loop do
|
8
|
+
str = SecureRandom.hex str_len
|
9
|
+
break str unless self.class.exists?(attr => str)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
module GrapeOnRails
|
5
|
+
module Sources
|
6
|
+
class YAMLSource
|
7
|
+
attr_accessor :path
|
8
|
+
|
9
|
+
def initialize path
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def load
|
14
|
+
@path && File.exist?(@path.to_s) ? YAML.safe_load(ERB.new(IO.read(@path.to_s)).result) : {}
|
15
|
+
rescue Psych::SyntaxError => e
|
16
|
+
raise "YAML syntax error occurred while parsing #{@path}. " \
|
17
|
+
"Error: #{e.message}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
class GrapeOnRails::StructuralHash < OpenStruct
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def from_hash hash
|
7
|
+
marshal_load __convert(hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_hash
|
11
|
+
{}.tap do |result|
|
12
|
+
marshal_dump.each{|k, v| result[k] = hash_value v}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def each *args, &block
|
17
|
+
marshal_dump.each(*args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
# Recursively converts Hashes to Options (including Hashes inside Arrays)
|
22
|
+
# rubocop:disable PerceivedComplexity
|
23
|
+
def __convert hash #:nodoc:
|
24
|
+
instance = self.class.new
|
25
|
+
hash.each do |k, v|
|
26
|
+
k = k.to_s if !k.respond_to?(:to_sym) && k.respond_to?(:to_s)
|
27
|
+
instance.new_ostruct_member k
|
28
|
+
if v.is_a?(Hash)
|
29
|
+
v = v["type"] == "hash" ? v["contents"] : __convert(v)
|
30
|
+
elsif v.is_a?(Array)
|
31
|
+
v = v.map{|e| e.instance_of?(Hash) ? __convert(e) : e}
|
32
|
+
end
|
33
|
+
instance.send "#{k}=".to_sym, v
|
34
|
+
end
|
35
|
+
instance
|
36
|
+
end
|
37
|
+
# rubocop:enable PerceivedComplexity
|
38
|
+
|
39
|
+
def hash_value value
|
40
|
+
if value.instance_of? GrapeOnRails::StructuralHash
|
41
|
+
value.to_hash
|
42
|
+
elsif v.instance_of? Array
|
43
|
+
descend_array(value)
|
44
|
+
else
|
45
|
+
value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "i18n"
|
2
|
+
|
3
|
+
module GrapeOnRails
|
4
|
+
module Support
|
5
|
+
def gor_translate error
|
6
|
+
GoR.errors.public_send(error).public_send(I18n.locale)
|
7
|
+
end
|
8
|
+
alias_method :gor_t, :gor_translate
|
9
|
+
|
10
|
+
def class_name instance
|
11
|
+
instance.class.name.demodulize.underscore
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GrapeOnRails
|
2
|
+
module Types
|
3
|
+
module Boolean
|
4
|
+
def to_b
|
5
|
+
case self
|
6
|
+
when "true"
|
7
|
+
true
|
8
|
+
when "false"
|
9
|
+
false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TrueClass
|
17
|
+
include GrapeOnRails::Types::Boolean
|
18
|
+
end
|
19
|
+
class FalseClass
|
20
|
+
include GrapeOnRails::Types::Boolean
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "grape_on_rails/macros"
|
2
|
+
|
3
|
+
module GrapeOnRails
|
4
|
+
module Validator
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
include GrapeOnRails::Macros
|
8
|
+
|
9
|
+
ALLOW_ACTIONS = /(create|update|destroy|index|show)/
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def validate_actions *actions
|
13
|
+
actions.each do |action|
|
14
|
+
meta_method = "before_action :validate_#{action}, only: :#{action}"
|
15
|
+
class_eval meta_method
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing method, *args, &block
|
20
|
+
action = extract_action method
|
21
|
+
super unless action&.match? ALLOW_ACTIONS
|
22
|
+
define_method "hook_#{action}", block
|
23
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
24
|
+
before_action :hook_#{action}, only: :#{action}
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
|
28
|
+
def respond_to_missing? method_name, include_private = false
|
29
|
+
extract_action(method_name)&.match?(ALLOW_ACTIONS) || super(method_name, include_private)
|
30
|
+
end
|
31
|
+
|
32
|
+
def extract_action method_name
|
33
|
+
method_name[/.+?(?=_params)/]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "grape_on_rails"
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Enable flags like --only-failures and --next-failure
|
6
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
7
|
+
|
8
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grape_on_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- topcbl
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.1'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.1'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activerecord
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.1'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '6'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '4.1'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '6'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: activesupport
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '4.1'
|
60
|
+
- - "<"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '6'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '4.1'
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '6'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: railties
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '4.1'
|
80
|
+
- - "<"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '6'
|
83
|
+
type: :runtime
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.1'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '6'
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: bundler
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '1.15'
|
100
|
+
type: :development
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '1.15'
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: rake
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '10.0'
|
114
|
+
type: :development
|
115
|
+
prerelease: false
|
116
|
+
version_requirements: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '10.0'
|
121
|
+
- !ruby/object:Gem::Dependency
|
122
|
+
name: rspec
|
123
|
+
requirement: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - "~>"
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '3.0'
|
128
|
+
type: :development
|
129
|
+
prerelease: false
|
130
|
+
version_requirements: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - "~>"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '3.0'
|
135
|
+
description: Bring Grape DSL to Rails-api. Make it easier for writing api.
|
136
|
+
email:
|
137
|
+
- topcbl@gmail.com
|
138
|
+
executables: []
|
139
|
+
extensions: []
|
140
|
+
extra_rdoc_files: []
|
141
|
+
files:
|
142
|
+
- ".gitignore"
|
143
|
+
- ".rspec"
|
144
|
+
- ".rubocop.yml"
|
145
|
+
- ".rubocop_disabled.yml"
|
146
|
+
- ".rubocop_enabled.yml"
|
147
|
+
- ".travis.yml"
|
148
|
+
- CODE_OF_CONDUCT.md
|
149
|
+
- Gemfile
|
150
|
+
- LICENSE.txt
|
151
|
+
- README.md
|
152
|
+
- Rakefile
|
153
|
+
- bin/console
|
154
|
+
- bin/setup
|
155
|
+
- grape_on_rails.gemspec
|
156
|
+
- lib/grape_on_rails.rb
|
157
|
+
- lib/grape_on_rails/api.rb
|
158
|
+
- lib/grape_on_rails/api_error.rb
|
159
|
+
- lib/grape_on_rails/attributes.rb
|
160
|
+
- lib/grape_on_rails/authenticator.rb
|
161
|
+
- lib/grape_on_rails/error_formatter.rb
|
162
|
+
- lib/grape_on_rails/integrations/railtie.rb
|
163
|
+
- lib/grape_on_rails/macros.rb
|
164
|
+
- lib/grape_on_rails/models.rb
|
165
|
+
- lib/grape_on_rails/models/user_actor.rb
|
166
|
+
- lib/grape_on_rails/models/user_token_actor.rb
|
167
|
+
- lib/grape_on_rails/secured_generator.rb
|
168
|
+
- lib/grape_on_rails/sources/yaml_source.rb
|
169
|
+
- lib/grape_on_rails/structural_hash.rb
|
170
|
+
- lib/grape_on_rails/support.rb
|
171
|
+
- lib/grape_on_rails/types/boolean.rb
|
172
|
+
- lib/grape_on_rails/validator.rb
|
173
|
+
- lib/grape_on_rails/version.rb
|
174
|
+
- spec/grape_on_rails_spec.rb
|
175
|
+
- spec/spec_helper.rb
|
176
|
+
homepage: https://github.com/chau-bao-long/grape-on-rails
|
177
|
+
licenses:
|
178
|
+
- MIT
|
179
|
+
metadata: {}
|
180
|
+
post_install_message:
|
181
|
+
rdoc_options: []
|
182
|
+
require_paths:
|
183
|
+
- lib
|
184
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ">="
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
requirements: []
|
195
|
+
rubyforge_project:
|
196
|
+
rubygems_version: 2.6.11
|
197
|
+
signing_key:
|
198
|
+
specification_version: 4
|
199
|
+
summary: Bring Grape DSL to Rails-api. Make it easier for writing api.
|
200
|
+
test_files: []
|