appbase 0.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/lib/appbase/controllers/app_base_controller.rb +165 -0
- data/lib/appbase/model_concern.rb +108 -0
- data/lib/appbase/railtie.rb +126 -0
- data/lib/appbase/registry.rb +60 -0
- data/lib/appbase/version.rb +3 -0
- data/lib/appbase.rb +3 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 21e5c0b2f097283d8f398c5ca323f8a68c1a3f8a
|
4
|
+
data.tar.gz: 8b9a0d23b5942695c3e34b1afce107208d0d2a38
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b05fb2ef0b47302f41b5f6740a152251975b4ad451acc5d7755aa6b2695830ffee91639af82c6e7accc6f964786f6b9afe7b996289f3aacbd8e152e75f251519
|
7
|
+
data.tar.gz: 0cea345d69931905d64301d26a69137332d8213978857b3ab05a63c7453cb0a0e4fd06d29bd66569862459b8f7f1f4a2b182c3ff559d7b29b3a65dbd0ad74e88
|
@@ -0,0 +1,165 @@
|
|
1
|
+
class AppBaseController < ActionController::Base
|
2
|
+
|
3
|
+
def version
|
4
|
+
render json: AppBase::VERSION
|
5
|
+
end
|
6
|
+
|
7
|
+
def current_user
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def define_useridentity(user_identity, token_store, token_key_user, token_key_session)
|
14
|
+
self.class_eval %-
|
15
|
+
def current_user(options={})
|
16
|
+
if #{token_store}[:#{token_key_user}].nil? || #{token_store}[:#{token_key_session}].nil?
|
17
|
+
return options[:default] if options.has_key? :default
|
18
|
+
raise "unauthenticated"
|
19
|
+
end
|
20
|
+
#{user_identity}.authenticate_by_token(#{token_store}[:#{token_key_user}], #{token_store}[:#{token_key_session}])
|
21
|
+
end
|
22
|
+
-
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_create_stub(model)
|
26
|
+
m = model.name
|
27
|
+
permits = model.columns.map { |item| item.name }.to_json
|
28
|
+
self.module_eval %-
|
29
|
+
def create_#{AppBase.underscore m}
|
30
|
+
obj = #{m}.new(params.except(:action, :controller, :id).permit(#{permits}))
|
31
|
+
if !#{m}.allow_create?(current_user, obj)
|
32
|
+
render json: { status: "error", msg: "unauthorized" }
|
33
|
+
else
|
34
|
+
obj.save!
|
35
|
+
render json: { status: 'ok', id: obj.id }
|
36
|
+
end
|
37
|
+
rescue Exception => e
|
38
|
+
render json: { status: 'error', msg: e.to_s }
|
39
|
+
end
|
40
|
+
-
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_update_stub(model)
|
44
|
+
m = model.name
|
45
|
+
permits = model.columns.map { |item| item.name }.to_json
|
46
|
+
self.module_eval %-
|
47
|
+
def update_#{AppBase.underscore m}
|
48
|
+
obj = #{m}.find(params[:id])
|
49
|
+
if obj.nil?
|
50
|
+
return render json: { status: 'error', msg: 'not_found' }
|
51
|
+
end
|
52
|
+
obj.update_attributes(params.except(:action, :controller, :id).permit(#{permits}))
|
53
|
+
if !#{m}.allow_update?(current_user, obj)
|
54
|
+
render json: { status: "error", msg: "unauthorized" }
|
55
|
+
else
|
56
|
+
obj.save!
|
57
|
+
render json: { status: 'ok' }
|
58
|
+
end
|
59
|
+
rescue Exception => e
|
60
|
+
render json: { status: 'error', msg: e.to_s }
|
61
|
+
end
|
62
|
+
-
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_delete_stub(model)
|
66
|
+
m = model.name
|
67
|
+
self.module_eval %-
|
68
|
+
def delete_#{AppBase.underscore m}
|
69
|
+
obj = #{m}.find(params[:id])
|
70
|
+
if obj.nil?
|
71
|
+
return render json: { status: 'error', msg: 'not_found' }
|
72
|
+
end
|
73
|
+
if !#{m}.allow_delete?(current_user, obj)
|
74
|
+
render json: { status: "error", msg: "unauthorized" }
|
75
|
+
else
|
76
|
+
obj.delete
|
77
|
+
render json: { status: 'ok' }
|
78
|
+
end
|
79
|
+
rescue Exception => e
|
80
|
+
render json: { status: 'error', msg: e.to_s }
|
81
|
+
end
|
82
|
+
-
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_query_stub(model)
|
86
|
+
m = model.name
|
87
|
+
columns = model.columns.map{|c|c.name}
|
88
|
+
self.class_eval %-
|
89
|
+
def query_#{AppBase.underscore m}
|
90
|
+
query = #{m}.accessible_by(current_user)
|
91
|
+
params.except(:action, :controller, :p, :ps).each { |k, v|
|
92
|
+
op = 'eq'
|
93
|
+
if k.index('.') && k.split('.').count == 2
|
94
|
+
k, op = k.split('.')
|
95
|
+
end
|
96
|
+
return if #{columns}.index(k).nil?
|
97
|
+
case op
|
98
|
+
when 'eq'
|
99
|
+
query = query.where "\#{k} = ?", v
|
100
|
+
when 'lt'
|
101
|
+
query = query.where "\#{k} < ?", v
|
102
|
+
when 'le'
|
103
|
+
query = query.where "\#{k} <= ?", v
|
104
|
+
when 'gt'
|
105
|
+
query = query.where "\#{k} > ?", v
|
106
|
+
when 'ge'
|
107
|
+
query = query.where "\#{k} >= ?", v
|
108
|
+
when 'n'
|
109
|
+
query = query.where "\#{k} IS NULL"
|
110
|
+
when 'nn'
|
111
|
+
query = query.where "\#{k} IS NOT NULL"
|
112
|
+
when 'in'
|
113
|
+
values = JSON.parse v
|
114
|
+
query = query.where "\#{k} IN (?)", values
|
115
|
+
when 'nin'
|
116
|
+
values = JSON.parse v
|
117
|
+
query = query.where "\#{k} NOT IN (?)", values
|
118
|
+
else
|
119
|
+
end
|
120
|
+
}
|
121
|
+
page_size = [1, (params[:ps]||20).to_i].max
|
122
|
+
start = [0, (params[:p]||1).to_i.pred].max * page_size
|
123
|
+
render json: { status: 'ok', data: query.offset(start).limit(page_size) }
|
124
|
+
rescue Exception => e
|
125
|
+
render json: { status: 'error', msg: e.to_s }
|
126
|
+
end
|
127
|
+
-
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_rpc_method_stub(bound_method, auth=false)
|
131
|
+
m = bound_method.receiver.name
|
132
|
+
mn = bound_method.name
|
133
|
+
parameters = bound_method.parameters
|
134
|
+
if auth && (parameters.count == 0 || parameters[0][0] != :req)
|
135
|
+
raise "#{m}.#{mn} does not accept current user identity as the first parameter. Using `expose_to_appbase :method_name, atuh: false` to expose #{m}.#{mn} to appbase without user authentication."
|
136
|
+
end
|
137
|
+
need_params = false
|
138
|
+
if parameters.last[0] == :opt
|
139
|
+
need_params = true
|
140
|
+
parameters = parameters[(auth ? 1 : 0)..-2]
|
141
|
+
else
|
142
|
+
parameters = parameters[(auth ? 1 : 0)..-1]
|
143
|
+
end
|
144
|
+
if parameters.find{|p|p[0]!=:req}
|
145
|
+
raise "Error exposing #{m}.#{mn} to appbase engine, appbase does not support rest/optional parameters, use options instead!"
|
146
|
+
end
|
147
|
+
requires = parameters.map{|p|":#{p[1]}"}
|
148
|
+
parameters = auth ? ['current_user'] : []
|
149
|
+
requires.each { |p| parameters << "params[#{p}]" }
|
150
|
+
if need_params
|
151
|
+
parameters.push "params.except(:action, :controller#{requires.count > 0 ? ", #{requires.join(', ')}" : ""})"
|
152
|
+
end
|
153
|
+
self.class_eval %-
|
154
|
+
def rpc_#{AppBase.underscore m}_#{mn}
|
155
|
+
#{requires.map{|p|"params.require #{p}"}.join(';')}
|
156
|
+
render json: { status: 'ok', data: #{m}.#{mn}(#{parameters.join(', ')}) }
|
157
|
+
rescue Exception => e
|
158
|
+
render json: { status: 'error', msg: e.to_s }
|
159
|
+
end
|
160
|
+
-
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module AppBase
|
4
|
+
|
5
|
+
module ModelConcern
|
6
|
+
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def expose_to_appbase(*method_names)
|
12
|
+
return if method_names.count == 0
|
13
|
+
options = {}
|
14
|
+
if method_names.last.instance_of? Hash
|
15
|
+
*method_names, options = method_names
|
16
|
+
end
|
17
|
+
method_names.each do |method_name|
|
18
|
+
AppBase::Registry.register_rpc self, method_name, options
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def appbase_allow(crud, criteria=:mine, &block)
|
23
|
+
if [:create, :update, :delete, :query].index(crud).nil?
|
24
|
+
raise "Unsupported crud operation: #{crud}, available options: create, update, delete, query"
|
25
|
+
end
|
26
|
+
model = self
|
27
|
+
if criteria == :mine
|
28
|
+
# allow_xxx :mine or simply allow_xxx
|
29
|
+
AppBase::Engine.after_initialized do
|
30
|
+
user_identity_attr = "#{AppBase::Engine::UserIdentity.underscore}_id"
|
31
|
+
model.class_eval crud == :query ? %-
|
32
|
+
def self.accessible_by(user)
|
33
|
+
#{model.name}.where(:#{user_identity_attr} => user.id)
|
34
|
+
end
|
35
|
+
- : %-
|
36
|
+
def self.allow_#{crud}?(user, obj)
|
37
|
+
user.id == obj.#{user_identity_attr}
|
38
|
+
end
|
39
|
+
-
|
40
|
+
end
|
41
|
+
elsif crud != :query && criteria == :if && block_given? && block.parameters.count == 2
|
42
|
+
# allow_xxx :if do; end
|
43
|
+
AppBase::Engine.after_initialized do
|
44
|
+
user_identity_attr = "#{AppBase::Engine::UserIdentity.underscore}_id"
|
45
|
+
model.define_singleton_method "allow_#{crud}".to_sym, &block
|
46
|
+
end
|
47
|
+
elsif crud == :query && criteria == :within && block_given? && block.parameters.count == 1
|
48
|
+
# allow_query :within {|current_user| Model.where(...)}
|
49
|
+
AppBase::Engine.after_initialized do
|
50
|
+
user_identity_attr = "#{AppBase::Engine::UserIdentity.underscore}_id"
|
51
|
+
model.define_singleton_method :accessible_by, &block
|
52
|
+
end
|
53
|
+
elsif crud != :query && riteria.instance_of?(Hash) && criteria.has_key?(:if) && criteria[:if].instance_of?(Symbol)
|
54
|
+
# :if => :a_singleton_method
|
55
|
+
AppBase::Engine.after_initialized do
|
56
|
+
user_identity_attr = "#{AppBase::Engine::UserIdentity.underscore}_id"
|
57
|
+
model.class_eval %-
|
58
|
+
def self.allow_#{crud}?(user, obj)
|
59
|
+
#{model.name}.#{criteria[:if]} user
|
60
|
+
end
|
61
|
+
-
|
62
|
+
end
|
63
|
+
elsif crud == :query && criteria.instance_of?(Hash) && criteria.has_key?(:within) && criteria[:within].instance_of?(Symbol)
|
64
|
+
# allow_query :within => :a_singleton_query_method
|
65
|
+
AppBase::Engine.after_initialized do
|
66
|
+
user_identity_attr = "#{AppBase::Engine::UserIdentity.underscore}_id"
|
67
|
+
model.class_eval %-
|
68
|
+
def self.accessible_by(user)
|
69
|
+
#{model.name}.#{criteria[:within]} user
|
70
|
+
end
|
71
|
+
-
|
72
|
+
end
|
73
|
+
else
|
74
|
+
raise %-
|
75
|
+
allow_#{crud} usage:
|
76
|
+
allow_#{crud} :mine
|
77
|
+
allow_#{crud} :#{ crud == :query ? 'within' : 'if' } => :a_singleton_method
|
78
|
+
allow_#{crud} :#{ crud == :query ? 'within' : 'if' } do |current_user_identity#{ crud == :query ? '' : ', model_instance' }|
|
79
|
+
# #{ crud == :query ? 'return fitlered query, e.g. Note.where(:user_id => current_user_identity.id)' : 'return true if allowed' }
|
80
|
+
end
|
81
|
+
-
|
82
|
+
end
|
83
|
+
AppBase::Registry.register_crud self, crud
|
84
|
+
end
|
85
|
+
|
86
|
+
def allow_create(criteria=:mine, &block)
|
87
|
+
self.appbase_allow(:create, criteria, &block)
|
88
|
+
end
|
89
|
+
|
90
|
+
def allow_update(criteria=:mine, &block)
|
91
|
+
self.appbase_allow(:update, criteria, &block)
|
92
|
+
end
|
93
|
+
|
94
|
+
def allow_delete(criteria=:mine, &block)
|
95
|
+
self.appbase_allow(:delete, criteria, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
def allow_query(criteria=:mine, &block)
|
99
|
+
self.appbase_allow(:query, criteria, &block)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
ActiveRecord::Base.include AppBase::ModelConcern
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require_relative "registry"
|
3
|
+
require_relative "model_concern"
|
4
|
+
require_relative "controllers/app_base_controller"
|
5
|
+
|
6
|
+
module AppBase
|
7
|
+
|
8
|
+
class Engine < Rails::Engine
|
9
|
+
|
10
|
+
paths["app/controllers"] = "lib/appbase/controllers"
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
initialized = false
|
15
|
+
config = nil
|
16
|
+
hooks = []
|
17
|
+
|
18
|
+
define_method :bootstrap do |app_config|
|
19
|
+
return if initialized
|
20
|
+
config = app_config.appbase
|
21
|
+
|
22
|
+
# initialize user identity
|
23
|
+
if config.user_identity.nil?
|
24
|
+
raise "AppBase configuration error: please use `config.appbase.user_identity = :UserIdentity` to specify the user identity model; and implement UserIdentity.authenticate_by_token(user, token):UserIdentity method."
|
25
|
+
end
|
26
|
+
user_identity = Object.const_get config.user_identity.to_sym
|
27
|
+
if !user_identity.respond_to?(:authenticate_by_token) || user_identity.method(:authenticate_by_token).parameters.count != 2
|
28
|
+
raise "It's required to implement UserIdentity.authenticate_by_token(user, token):UserIdentity method."
|
29
|
+
end
|
30
|
+
AppBase::Engine::UserIdentity = config.user_identity.to_s.extend AppBase::StringExtension
|
31
|
+
AppBaseController.define_useridentity config.user_identity, config.token_store, config.token_key_user, config.token_key_session
|
32
|
+
|
33
|
+
# initialize crud stubs
|
34
|
+
AppBase::Registry.each_crud config.models do |model, op|
|
35
|
+
model_name_underscore = AppBase.underscore model.name
|
36
|
+
case op
|
37
|
+
when :create
|
38
|
+
AppBaseController.add_create_stub(model)
|
39
|
+
AppBase::Engine.routes.append do
|
40
|
+
put "/#{model_name_underscore}" => "app_base#create_#{model_name_underscore}"
|
41
|
+
end
|
42
|
+
when :update
|
43
|
+
AppBaseController.add_update_stub(model)
|
44
|
+
AppBase::Engine.routes.append do
|
45
|
+
put "/#{model_name_underscore}/:id" => "app_base#update_#{model_name_underscore}"
|
46
|
+
end
|
47
|
+
when :delete
|
48
|
+
AppBaseController.add_delete_stub(model)
|
49
|
+
AppBase::Engine.routes.append do
|
50
|
+
delete "/#{model_name_underscore}/:id" => "app_base#delete_#{model_name_underscore}"
|
51
|
+
end
|
52
|
+
when :query
|
53
|
+
AppBaseController.add_query_stub(model)
|
54
|
+
AppBase::Engine.routes.append do
|
55
|
+
get "/#{model_name_underscore}" => "app_base#query_#{model_name_underscore}"
|
56
|
+
end
|
57
|
+
else
|
58
|
+
raise "Unexpected crud operation: #{op}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# initialize rpc stubs
|
63
|
+
AppBase::Registry.each_rpc do |r|
|
64
|
+
if !r[:model].respond_to? r[:method]
|
65
|
+
raise "#{r[:model].name} does not respond to #{r[:method]}."
|
66
|
+
end
|
67
|
+
bound_method = r[:model].method r[:method]
|
68
|
+
AppBaseController.add_rpc_method_stub(bound_method, r[:auth])
|
69
|
+
AppBase::Engine.routes.append do
|
70
|
+
post "/#{AppBase.underscore r[:model].name}/#{r[:method]}" => "app_base#rpc_#{AppBase.underscore r[:model].name}_#{r[:method]}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# finalize appbase routes
|
75
|
+
AppBase::Engine.routes.draw do
|
76
|
+
get "/appbase_version" => "app_base#version"
|
77
|
+
end
|
78
|
+
|
79
|
+
# after initialized
|
80
|
+
blocks, hooks = hooks, []
|
81
|
+
blocks.each do |block|
|
82
|
+
block.call
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
define_method :after_initialized do |&block|
|
88
|
+
if initialized
|
89
|
+
block.call
|
90
|
+
else
|
91
|
+
hooks << block
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
define_method :config do
|
96
|
+
config
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
class Railtie < Rails::Railtie
|
104
|
+
|
105
|
+
# default values for appbase configuration
|
106
|
+
config.appbase = ActiveSupport::OrderedOptions.new
|
107
|
+
config.appbase.mount = "/appbase"
|
108
|
+
config.appbase.user_identity = nil
|
109
|
+
config.appbase.token_store = :cookies # :cookies, :headers, :params
|
110
|
+
config.appbase.token_key_user = :u
|
111
|
+
config.appbase.token_key_session = :s
|
112
|
+
config.appbase.models = []
|
113
|
+
|
114
|
+
initializer "appbase.configure_route", :after => :add_routing_paths do |app|
|
115
|
+
|
116
|
+
AppBase::Engine.bootstrap app.config
|
117
|
+
|
118
|
+
app.routes.append do
|
119
|
+
mount AppBase::Engine => Rails.application.config.appbase.mount
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module AppBase
|
2
|
+
|
3
|
+
def self.underscore(str)
|
4
|
+
str.gsub(/::/, '/').
|
5
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
6
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
7
|
+
tr("-", "_").
|
8
|
+
downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
module StringExtension
|
12
|
+
|
13
|
+
def underscore
|
14
|
+
AppBase.underscore self
|
15
|
+
end
|
16
|
+
self
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
module Registry
|
21
|
+
|
22
|
+
class << Registry
|
23
|
+
|
24
|
+
rpc_methods = []
|
25
|
+
crud_permissions = []
|
26
|
+
|
27
|
+
define_method :register_rpc do |model, method_name, options={}|
|
28
|
+
model = Object.const_get(model.to_sym) if model.instance_of?(String) || model.instance_of?(Symbol)
|
29
|
+
method_name = method_name.to_sym
|
30
|
+
auth = options.has_key?(:auth) ? options[:auth] : true
|
31
|
+
if rpc_methods.find{ |r| r[:model] == model && r[:method] == method_name }.nil?
|
32
|
+
rpc_methods << { model: model, method: method_name, auth: auth }
|
33
|
+
else
|
34
|
+
raise "#{model}.#{method_name} has already been registered"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
define_method :each_rpc do |&block|
|
39
|
+
rpc_methods.each &block
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method :register_crud do |model, crud|
|
43
|
+
if crud_permissions.find{ |r| r[:model] == model && r[:crud] == crud }.nil?
|
44
|
+
crud_permissions << { model: model, crud: crud }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
define_method :each_crud do |*models, &block|
|
49
|
+
models = models[0] if models.count == 1 && models.instance_of?(Array)
|
50
|
+
models = models.map { |model| (model.instance_of?(Symbol) || model.instance_of?(String)) ? Object.const_get(model) : model }
|
51
|
+
crud_permissions.each do |r|
|
52
|
+
block.call r[:model], r[:crud] if models.index(r[:model])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/lib/appbase.rb
ADDED
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: appbase
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- bestmike007
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.7
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.7
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.0'
|
83
|
+
description: A lightweight backend for Web/iOS/Android apps.
|
84
|
+
email: i@bestmike007.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- lib/appbase.rb
|
90
|
+
- lib/appbase/controllers/app_base_controller.rb
|
91
|
+
- lib/appbase/model_concern.rb
|
92
|
+
- lib/appbase/railtie.rb
|
93
|
+
- lib/appbase/registry.rb
|
94
|
+
- lib/appbase/version.rb
|
95
|
+
homepage: http://bestmike007.com/appbase
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.4.3
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Lightweight appbase
|
119
|
+
test_files: []
|