weapon 0.1.1 → 0.1.2
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/lib/generators/weapon/activeadmin/activeadmin_generator.rb +47 -29
- data/lib/generators/weapon/grape/grape_generator.rb +41 -26
- data/lib/generators/weapon/grape/templates/auth/authenticator.rb +86 -0
- data/lib/generators/weapon/grape/templates/auth/middleware.rb +35 -0
- data/lib/generators/weapon/grape/templates/auth/utils.rb +28 -0
- data/lib/generators/weapon/grape/templates/dispatch.rb +13 -0
- data/lib/generators/weapon/grape/templates/errors.rb +81 -0
- data/lib/generators/weapon/grape/templates/helpers.rb +24 -0
- data/lib/generators/weapon/grape/templates/named_params.rb +14 -0
- data/lib/generators/weapon/grape_entity/grape_entity_generator.rb +55 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8621ad57230f376e88746ffb2ca40f8957f7d483
|
4
|
+
data.tar.gz: 969cb6e67bdc34eec0263004c0887896edc189f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5641986317808d41699ffa477bd7e34c5edbeaedb5cd8dd5524f3f3649ab3f923fabd85c6a62bff9cc1a79b3c7d3ce7359162d6d0e20f3b15ec8ae03703f276d
|
7
|
+
data.tar.gz: 015e1e722924516d70c47c74aaeaa305f33e3a087993daf3cdd7ebe5edb4fa473f4984d0c694d8423105b62682df12bd2f5765d01b6ebd701ce0d101e86ac0af
|
@@ -1,36 +1,54 @@
|
|
1
1
|
|
2
2
|
class Weapon::ActiveadminGenerator < Rails::Generators::NamedBase # :nodoc:
|
3
|
-
desc 'This generator creates
|
4
|
-
|
5
|
-
def create_example_email
|
6
|
-
application(nil, env: "production") do
|
7
|
-
config.action_mailer.raise_delivery_errors = true
|
8
|
-
config.action_mailer.default_url_options = {:host => '120.25.61.54:8100'}
|
9
|
-
config.action_mailer.delivery_method = :smtp
|
10
|
-
config.action_mailer.smtp_settings = {
|
11
|
-
:address => "smtp.163.com",
|
12
|
-
:port => 25,
|
13
|
-
:user_name => "ledcloud@163.com",
|
14
|
-
:password => "ffgexobhlolfjhij",
|
15
|
-
:enable_starttls_auto => true,
|
16
|
-
:authentication => "plain",
|
17
|
-
:domain => "163.com"
|
18
|
-
}
|
19
|
-
end
|
20
|
-
end
|
3
|
+
desc 'This generator creates activeadmin files'
|
21
4
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
5
|
+
class_option :only, type: :string, desc: 'only generate model for listed model'
|
6
|
+
class_option :except, type: :string, desc: 'when generate model, exclude listed model'
|
7
|
+
|
8
|
+
def generate_activeadmin
|
9
|
+
|
10
|
+
prefix = 'app/admin'
|
11
|
+
|
12
|
+
if args[0].nil? || args[0] == "all"
|
13
|
+
names = Dir["app/models/*.rb"].map {|x| File.basename(x, '.rb')}
|
14
|
+
|
15
|
+
if options[:only]
|
16
|
+
names = names & options[:only].split(',')
|
17
|
+
end
|
18
|
+
|
19
|
+
if options[:except]
|
20
|
+
names = names - options[:except].split(',')
|
21
|
+
end
|
22
|
+
|
23
|
+
names.each do |name|
|
24
|
+
next unless name.camelize.constantize.respond_to? 'column_names'
|
25
|
+
column_names = name.camelize.constantize.column_names
|
26
|
+
infos = column_names.map {|column| "expose :#{column}"}
|
27
|
+
end
|
28
|
+
else
|
29
|
+
name = args[0]
|
30
|
+
return unless name.camelize.constantize.respond_to? 'column_names'
|
31
|
+
column_names = name.camelize.constantize.column_names
|
32
|
+
|
33
|
+
if options[:only]
|
34
|
+
column_names = column_names & options[:only].split(',')
|
35
|
+
end
|
36
|
+
|
37
|
+
if options[:except]
|
38
|
+
column_names = column_names - options[:except].split(',')
|
39
|
+
end
|
40
|
+
|
41
|
+
ap column_names
|
42
|
+
a = Magicfile.new
|
43
|
+
infos = ['xx']
|
44
|
+
a.append_string_lines(infos)
|
45
|
+
a.to_file "#{prefix}/name.rb"
|
26
46
|
|
27
|
-
application(nil, env: "production") do
|
28
|
-
config.middleware.use ExceptionNotification::Rack,
|
29
|
-
:email => {
|
30
|
-
:email_prefix => "[weapon] ",
|
31
|
-
:sender_address => "weapon <ledcloud@163.com>",
|
32
|
-
:exception_recipients => %w{dilin.life@gmail.com}
|
33
|
-
}
|
34
47
|
end
|
48
|
+
|
49
|
+
|
50
|
+
|
35
51
|
end
|
52
|
+
|
53
|
+
|
36
54
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
require 'magicfile'
|
2
2
|
require 'fileutils'
|
3
|
-
|
3
|
+
require 'thor'
|
4
4
|
|
5
5
|
class Weapon::GrapeGenerator < Rails::Generators::Base # :nodoc:
|
6
|
-
desc 'This generator creates grape
|
6
|
+
desc 'This generator creates basic grape files for models'
|
7
|
+
include Thor::Actions
|
7
8
|
|
8
|
-
|
9
|
+
source_root File.expand_path("../templates", __FILE__)
|
10
|
+
class_option :only, type: :string, desc: 'only generate api for listed model'
|
11
|
+
class_option :except, type: :string, desc: 'when generate api, exclude listed model'
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
prefix = prefix_dirs[0]
|
15
|
-
else
|
16
|
-
prefix = ask('there are multi directory in app/api directory, please input path like app/api/v1')
|
17
|
-
end
|
13
|
+
def generate_grape_files
|
14
|
+
|
15
|
+
prefix = 'app/api/v1'
|
16
|
+
FileUtils.mkdir_p prefix
|
18
17
|
|
19
18
|
if args[0].nil? || args[0] == "all"
|
20
19
|
names = Dir["app/models/*.rb"].map {|x| File.basename(x, '.rb')}
|
@@ -22,28 +21,44 @@ class Weapon::GrapeGenerator < Rails::Generators::Base # :nodoc:
|
|
22
21
|
names = args
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
entity_dir = File.join(prefix, "entities")
|
29
|
-
entity_path = File.join(entity_dir, "#{name}.rb")
|
30
|
-
|
31
|
-
ap "dir is #{entity_dir}"
|
32
|
-
ap "path is #{entity_path}"
|
24
|
+
if options[:only]
|
25
|
+
names = names & options[:only].split(',')
|
26
|
+
end
|
33
27
|
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
if options[:except]
|
29
|
+
names = names - options[:except].split(',')
|
30
|
+
end
|
37
31
|
|
38
|
-
|
32
|
+
module_array = prefix.split('/')[1..-1]
|
33
|
+
names.each do |name|
|
39
34
|
a = Magicfile.new
|
40
|
-
module_array = prefix.split('/')[1..-1].append('entities')
|
41
35
|
a.append_modules(module_array)
|
42
|
-
a.append_class(name.camelize, 'Grape::
|
36
|
+
a.append_class(name.camelize.pluralize, 'Grape::API')
|
37
|
+
infos = ["version 'v1', using: :path", "format :json", "default_format: json"]
|
43
38
|
a.append_string_lines(infos)
|
44
|
-
a.to_file
|
39
|
+
a.to_file "#{prefix}/#{name.pluralize}.rb"
|
45
40
|
end
|
46
41
|
|
42
|
+
b = Magicfile.new
|
43
|
+
b.append_modules(module_array)
|
44
|
+
b.append_class('Root', 'Grape::API')
|
45
|
+
infos = ["helpers Api::V1::Helpers", "version 'v1', using: :path", "cascade false", "format :json", "default_format :json\n", "use Api::V1::Auth::Middleware\n"]
|
46
|
+
infos += names.map {|x| "mount Api::V1::#{x.camelize.pluralize}"}
|
47
|
+
infos += ["\n", "before do", " header 'Access-Control-Allow-Origin'", "end\n"]
|
48
|
+
b.append_string_lines(infos)
|
49
|
+
b.to_file "#{prefix}/root.rb"
|
50
|
+
|
51
|
+
copy_file 'dispatch.rb', "app/api/dispatch.rb"
|
52
|
+
copy_file 'errors.rb', "#{prefix}/errors.rb"
|
53
|
+
copy_file 'helpers.rb', "#{prefix}/helpers.rb"
|
54
|
+
copy_file 'named_params.rb', "#{prefix}/named_params.rb"
|
55
|
+
FileUtils.mkdir_p "#{prefix}/auth"
|
56
|
+
copy_file 'auth/utils.rb', "#{prefix}/auth/utils.rb"
|
57
|
+
copy_file 'auth/middleware.rb', "#{prefix}/auth/middleware.rb"
|
58
|
+
copy_file 'auth/authenticator.rb', "#{prefix}/auth/authenticator.rb"
|
59
|
+
|
60
|
+
route "mount Api::Dispatch => '/api'"
|
61
|
+
|
47
62
|
end
|
48
63
|
|
49
64
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
module Auth
|
4
|
+
class Authenticator
|
5
|
+
|
6
|
+
def initialize(request, params)
|
7
|
+
@request = request
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def authenticate!
|
13
|
+
check_user!
|
14
|
+
check_tonce!
|
15
|
+
check_signature!
|
16
|
+
user
|
17
|
+
end
|
18
|
+
|
19
|
+
def user
|
20
|
+
@user ||= User.where(access_key: @params[:access_key]).first
|
21
|
+
end
|
22
|
+
|
23
|
+
def check_user!
|
24
|
+
raise InvalidAccessKeyError, @params[:access_key] unless user
|
25
|
+
raise ExpiredAccessKeyError, @params[:access_key] if user.auth_expired?
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_signature!
|
29
|
+
Rails.logger.warn "payload is #{payload}"
|
30
|
+
Rails.logger.warn "uploaded signature is #{@params[:signature]}"
|
31
|
+
Rails.logger.warn "generated signature is #{Utils.hmac_signature(user.secret_key, payload)}"
|
32
|
+
if @params[:signature] != Utils.hmac_signature(user.secret_key, payload)
|
33
|
+
Rails.logger.warn "Api v1 auth failed: signature doesn't match. token: #{user.access_key} payload: #{payload}"
|
34
|
+
raise Api::V1::IncorrectSignatureError, @params[:signature]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_tonce!
|
39
|
+
key = "api:v1:tonce:#{user.access_key}:#{tonce}"
|
40
|
+
if Utils.cache.read(key)
|
41
|
+
Rails.logger.warn "API v1 auth failed: used tonce.access_key: #{user.access_key} payload: #{payload} tonce: #{tonce}"
|
42
|
+
raise Api::V1::TonceUsedError.new(user.access_key, tonce)
|
43
|
+
end
|
44
|
+
Utils.cache.write key, tonce, 61 # forget after 61 seconds
|
45
|
+
|
46
|
+
now = Time.now.to_i
|
47
|
+
if tonce < now-30 || tonce > now+30# within 30 seconds
|
48
|
+
Rails.logger.warn "Api v1 auth failed: invalid tonce. access_key: #{user.access_key} payload: #{payload} tonce: #{tonce} current timestamp: #{now}"
|
49
|
+
raise Api::V1::InvalidTonceError.new(tonce, now)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def tonce
|
54
|
+
@tonce ||= @params[:tonce].to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def payload
|
58
|
+
"#{canonical_verb}|#{Api::V1::Root::PREFIX}#{canonical_uri}|#{canonical_query}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def canonical_verb
|
62
|
+
@request.request_method
|
63
|
+
end
|
64
|
+
|
65
|
+
def canonical_uri
|
66
|
+
@request.path_info
|
67
|
+
end
|
68
|
+
|
69
|
+
def canonical_query
|
70
|
+
hash = @params.select {|k,v| !%w(route_info signature format).include?(k) }
|
71
|
+
ap hash
|
72
|
+
URI.unescape(hash.to_param)
|
73
|
+
end
|
74
|
+
|
75
|
+
def endpoint
|
76
|
+
@request.env['api.endpoint']
|
77
|
+
end
|
78
|
+
|
79
|
+
def route_scopes
|
80
|
+
endpoint.options[:route_options][:scopes]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
module Auth
|
4
|
+
class Middleware < ::Grape::Middleware::Base
|
5
|
+
|
6
|
+
def before
|
7
|
+
#raise AuthorizationError
|
8
|
+
if provided?
|
9
|
+
auth = Api::V1::Auth::Authenticator.new(request, params)
|
10
|
+
ap "do auth"
|
11
|
+
@env['user'] = auth.authenticate!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def provided?
|
16
|
+
ap params
|
17
|
+
ap params["access_key"]
|
18
|
+
ap params["tonce"]
|
19
|
+
ap params["signature"]
|
20
|
+
params["access_key"] && params["tonce"] && params["signature"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def request
|
24
|
+
@request ||= ::Grape::Request.new(env)
|
25
|
+
end
|
26
|
+
|
27
|
+
def params
|
28
|
+
@params ||= request.params
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
module Auth
|
4
|
+
module Utils
|
5
|
+
class <<self
|
6
|
+
|
7
|
+
def cache
|
8
|
+
# Simply use rack-attack cache wrapper
|
9
|
+
@cache ||= Rack::Attack::Cache.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def urlsafe_string_40
|
13
|
+
# 30 is picked so generated string length is 40
|
14
|
+
SecureRandom.urlsafe_base64(30).tr('_-', 'xx')
|
15
|
+
end
|
16
|
+
|
17
|
+
alias :generate_access_key :urlsafe_string_40
|
18
|
+
alias :generate_secret_key :urlsafe_string_40
|
19
|
+
|
20
|
+
def hmac_signature(secret_key, payload)
|
21
|
+
OpenSSL::HMAC.hexdigest 'SHA256', secret_key, payload
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
|
4
|
+
module ExceptionHandlers
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.instance_eval do
|
8
|
+
rescue_from Grape::Exceptions::ValidationErrors do |e|
|
9
|
+
Rack::Response.new({
|
10
|
+
success: false,
|
11
|
+
message: e.message,
|
12
|
+
data: {}
|
13
|
+
}.to_json, e.status)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class Error < Grape::Exceptions::Base
|
21
|
+
attr :code, :text
|
22
|
+
|
23
|
+
# code: api error code defined by Peatio, errors originated from
|
24
|
+
# subclasses of Error have code start from 2000.
|
25
|
+
# text: human readable error message
|
26
|
+
# status: http status code
|
27
|
+
def initialize(opts={})
|
28
|
+
@text = opts[:text] || ''
|
29
|
+
|
30
|
+
@status = 200
|
31
|
+
@message = {success: false, message: @text, data: {}}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class AuthorizationError < Error
|
36
|
+
def initialize
|
37
|
+
super code: 2001, text: 'Authorization failed', status: 401
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
class IncorrectSignatureError < Error
|
44
|
+
def initialize(signature)
|
45
|
+
super code: 2005, text: "Signature #{signature} is incorrect.", status: 401
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class TonceUsedError < Error
|
50
|
+
def initialize(access_key, tonce)
|
51
|
+
super code: 2006, text: "The tonce #{tonce} has already been used by access key #{access_key}.", status: 401
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class InvalidTonceError < Error
|
56
|
+
def initialize(tonce, now)
|
57
|
+
super code: 2007, text: "The tonce #{tonce} is invalid, current timestamp is #{now}.", status: 401
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class InvalidAccessKeyError < Error
|
62
|
+
def initialize(access_key)
|
63
|
+
super code: 2008, text: "The access key #{access_key} does not exist.", status: 401
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class DisabledAccessKeyError < Error
|
68
|
+
def initialize(access_key)
|
69
|
+
super code: 2009, text: "The access key #{access_key} is disabled.", status: 401
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class ExpiredAccessKeyError < Error
|
74
|
+
def initialize(access_key)
|
75
|
+
super code: 2010, text: "The access key #{access_key} has expired.", status: 401
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
module Helpers
|
4
|
+
def render_success(data = {}, msg = nil)
|
5
|
+
status 200
|
6
|
+
{ success: true, message: msg.to_s, data: data }
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_fail(msg = nil, data = {})
|
10
|
+
status 200
|
11
|
+
{ success: false, message: msg.to_s, data: data }
|
12
|
+
end
|
13
|
+
|
14
|
+
def authenticate!
|
15
|
+
current_user or raise AuthorizationError
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_user
|
19
|
+
@user ||= env['user']
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Api
|
2
|
+
module V1
|
3
|
+
module NamedParams
|
4
|
+
extend ::Grape::API::Helpers
|
5
|
+
|
6
|
+
params :auth do
|
7
|
+
requires :access_key, type: String, desc: "Access key."
|
8
|
+
requires :tonce, type: Integer, desc: "Tonce is an integer represents the milliseconds elapsed since Unix epoch."
|
9
|
+
requires :signature, type: String, desc: "The signature of your request payload, generated using your secret key."
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'magicfile'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
|
5
|
+
class Weapon::GrapeEntityGenerator < Rails::Generators::Base # :nodoc:
|
6
|
+
desc 'This generator creates grape entity for model'
|
7
|
+
|
8
|
+
class_option :only, type: :string, desc: 'only generate api for listed model'
|
9
|
+
class_option :except, type: :string, desc: 'when generate api, exclude listed model'
|
10
|
+
|
11
|
+
def generate_grape_entity
|
12
|
+
|
13
|
+
prefix_dirs = Dir.glob('app/api/*/')
|
14
|
+
if prefix_dirs.count == 0
|
15
|
+
prefix = 'app/api/v1'
|
16
|
+
elsif prefix_dirs.count == 1
|
17
|
+
prefix = prefix_dirs[0]
|
18
|
+
else
|
19
|
+
prefix = ask('there are multi directory in app/api directory, please input path like app/api/v1')
|
20
|
+
end
|
21
|
+
|
22
|
+
if args[0].nil? || args[0] == "all"
|
23
|
+
names = Dir["app/models/*.rb"].map {|x| File.basename(x, '.rb')}
|
24
|
+
else
|
25
|
+
names = args
|
26
|
+
end
|
27
|
+
|
28
|
+
if options[:only]
|
29
|
+
names = names & options[:only].split(',')
|
30
|
+
end
|
31
|
+
|
32
|
+
if options[:except]
|
33
|
+
names = names - options[:except].split(',')
|
34
|
+
end
|
35
|
+
|
36
|
+
names.each do |name|
|
37
|
+
entity_dir = File.join(prefix, "entities")
|
38
|
+
entity_path = File.join(entity_dir, "#{name}.rb")
|
39
|
+
|
40
|
+
next unless name.camelize.constantize.respond_to? 'column_names'
|
41
|
+
column_names = name.camelize.constantize.column_names
|
42
|
+
infos = column_names.map {|column| "expose :#{column}"}
|
43
|
+
|
44
|
+
FileUtils.mkdir_p entity_dir
|
45
|
+
a = Magicfile.new
|
46
|
+
module_array = prefix.split('/')[1..-1].append('entities')
|
47
|
+
a.append_modules(module_array)
|
48
|
+
a.append_class(name.camelize, 'Grape::Entity')
|
49
|
+
a.append_string_lines(infos)
|
50
|
+
a.to_file entity_path
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weapon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- seaify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -92,6 +92,14 @@ files:
|
|
92
92
|
- lib/generators/weapon/activeadmin/activeadmin_generator.rb
|
93
93
|
- lib/generators/weapon/email/email_generator.rb
|
94
94
|
- lib/generators/weapon/grape/grape_generator.rb
|
95
|
+
- lib/generators/weapon/grape/templates/auth/authenticator.rb
|
96
|
+
- lib/generators/weapon/grape/templates/auth/middleware.rb
|
97
|
+
- lib/generators/weapon/grape/templates/auth/utils.rb
|
98
|
+
- lib/generators/weapon/grape/templates/dispatch.rb
|
99
|
+
- lib/generators/weapon/grape/templates/errors.rb
|
100
|
+
- lib/generators/weapon/grape/templates/helpers.rb
|
101
|
+
- lib/generators/weapon/grape/templates/named_params.rb
|
102
|
+
- lib/generators/weapon/grape_entity/grape_entity_generator.rb
|
95
103
|
- lib/generators/weapon/i18n/i18n_generator.rb
|
96
104
|
- lib/support/create_gem/basic.bin
|
97
105
|
- lib/support/create_gem/basic.gemspec
|