menilite 0.1.0 → 0.2.0

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
  SHA1:
3
- metadata.gz: 8bd4f42ddb852546849eaf34e1ad3247d19b7365
4
- data.tar.gz: 572240d87bfb87dc8c75747a427e3e6e4ed08afe
3
+ metadata.gz: e96823093a09cbe81fe57e93acb586d480258fb6
4
+ data.tar.gz: 1c1698195f5afb071265a644f0b5f725d04fc1a3
5
5
  SHA512:
6
- metadata.gz: 6c3cfffbe205a5c878560d0fa28aee2d357ce4351b277c8f134dcdf6c6257d0a3aae86f0eb500eb37e1ee54cfece83c3d66a4c211179bde49f596afaff4fd30b
7
- data.tar.gz: 157c094db9e46ecf109730510cdcbfa8c82d7592d99d0f37a47708c20fa78d3b096349a331f44e0566c64de2bb731db383fa67e98a8304b01b2b175810f8c68a
6
+ metadata.gz: 16f926123ff653a696b6b1fea7477de86fa51fe2776708202886518c214cce4284f6e47a043df4d285804793c12dc2a262793ccb3f8f71be1157a6c98af464b0
7
+ data.tar.gz: a5190655a95e355561b5f15f55fe96bd7d654134aad86bf46678a115cccd52e537ee9fd205ec34565a0111f5077e76d28f76fe95baf561cb0c9a3ff9173dd014
@@ -1,5 +1,7 @@
1
1
  require "menilite/version"
2
2
 
3
+ require "menilite/helper"
4
+
3
5
  if RUBY_ENGINE == "opal"
4
6
  require 'menilite/model'
5
7
  require 'menilite/controller'
@@ -8,9 +10,13 @@ else
8
10
  require 'opal'
9
11
  require 'menilite/model'
10
12
  require 'menilite/controller'
13
+ require 'menilite/privilege'
11
14
  require 'menilite/router'
12
15
  require 'menilite/server/activerecord_store'
13
16
 
14
17
  Opal.append_path File.expand_path('../', __FILE__).untaint
15
18
  Opal.append_path File.expand_path('../../vendor', __FILE__).untaint
16
19
  end
20
+
21
+ module Menilite
22
+ end
@@ -0,0 +1,23 @@
1
+ module Menilite
2
+ module Helper
3
+ def server?
4
+ !client?
5
+ end
6
+
7
+ def client?
8
+ RUBY_ENGINE == 'opal'
9
+ end
10
+
11
+ def if_server(&block)
12
+ block.call if server?
13
+ end
14
+
15
+ def if_client(&block)
16
+ block.call if client?
17
+ end
18
+ end
19
+
20
+ class << self
21
+ include Helper
22
+ end
23
+ end
@@ -1,5 +1,6 @@
1
1
  require 'securerandom'
2
- if RUBY_ENGINE == 'opal'
2
+
3
+ Menilite.if_client do
3
4
  require 'browser/http'
4
5
  require 'opal-parser'
5
6
  end
@@ -13,15 +14,18 @@ end
13
14
 
14
15
  module Menilite
15
16
  class Model
17
+ include Menilite::Helper
18
+
16
19
  attr_reader :fields
17
20
 
18
21
  def initialize(fields = {})
19
22
  self.class.init
20
23
 
21
- if RUBY_ENGINE == 'opal'
24
+ if client?
22
25
  fields = fields.clone
23
26
  else
24
27
  fields = fields.map{|k,v| [k.to_sym, v] }.to_h
28
+ fields.merge!(self.class.privilege_fields)
25
29
  end
26
30
 
27
31
  defaults = self.class.field_info.map{|k, d| [d.name, d.params[:default]] if d.params.has_key?(:default) }.compact.to_h
@@ -42,11 +46,11 @@ module Menilite
42
46
  def update(data)
43
47
  case data
44
48
  when self.class
45
- @fields.merge(data.fields)
49
+ @fields.merge!(data.fields)
46
50
  when Hash
47
- @fields.merge(data)
51
+ @fields.merge!(data.map{|k, v| resolve_references(k, v) }.to_h)
48
52
  when String
49
- @fields.merge(JSON.parse(json))
53
+ @fields.merge!(JSON.parse(json))
50
54
  end
51
55
  end
52
56
 
@@ -67,6 +71,8 @@ module Menilite
67
71
  end
68
72
 
69
73
  class << self
74
+ include Menilite::Helper
75
+
70
76
  def init
71
77
  if Model.subclasses.has_key?(self) && !Model.subclasses[self]
72
78
  store.register(self)
@@ -97,9 +103,14 @@ module Menilite
97
103
  store.delete(self)
98
104
  end
99
105
 
100
- def fetch(filter: nil, order: nil)
106
+ def fetch(filter: {}, order: nil)
101
107
  self.init
102
- filter = filter.map{|k, v| type_convert(k, v) }.to_h if filter
108
+ filter = filter.map{|k, v| type_convert(k, v) }.to_h
109
+
110
+ if_server do
111
+ filter.merge!(privilege_filter)
112
+ end
113
+
103
114
  store.fetch(self, filter: filter, order: order) do |list|
104
115
  yield list if block_given?
105
116
  list
@@ -135,7 +146,7 @@ module Menilite
135
146
  def field(name, type = :string, params = {})
136
147
  params.merge!(client: true, server: true)
137
148
 
138
- if RUBY_ENGINE == 'opal'
149
+ if client?
139
150
  return unless params[:client]
140
151
  else
141
152
  return unless params[:server]
@@ -178,7 +189,15 @@ module Menilite
178
189
 
179
190
  def action(name, options = {}, &block)
180
191
  action_info[name.to_s] = ActionInfo.new(name, block.parameters, options)
181
- if RUBY_ENGINE == 'opal'
192
+ if server?
193
+ self.instance_eval do
194
+ if options[:class]
195
+ define_singleton_method(name, block)
196
+ else
197
+ define_method(name, block)
198
+ end
199
+ end
200
+ else
182
201
  method = Proc.new do |model, *args, &callback| # todo: should adopt keyword parameters
183
202
  action_url = options[:on_create] || options[:class] ? "api/#{self}/#{name}" : "api/#{self}/#{model.id}/#{name}"
184
203
  post_data = {}
@@ -201,14 +220,6 @@ module Menilite
201
220
  define_method(name) {|*args, &callback| method.call(self, *args, &callback) }
202
221
  end
203
222
  end
204
- else
205
- self.instance_eval do
206
- if options[:class]
207
- define_singleton_method(name, block)
208
- else
209
- define_method(name, block)
210
- end
211
- end
212
223
  end
213
224
  end
214
225
 
@@ -233,6 +244,37 @@ module Menilite
233
244
  self.init
234
245
  store.max(self, field_name)
235
246
  end
247
+
248
+ def permit(privileges)
249
+ Menilite.if_server do
250
+ case privileges
251
+ when Array
252
+ self.privileges.push(*privileges)
253
+ when Symbol, String
254
+ self.privileges << privileges
255
+ end
256
+ end
257
+ end
258
+
259
+ Menilite.if_server do
260
+ def privileges
261
+ @privileges ||= []
262
+ end
263
+
264
+ def privilege_filter
265
+ return {} unless PrivilegeService.current
266
+ PrivilegeService.current.get_privileges(self.privileges).each_with_object({}) do |priv, filter|
267
+ filter.merge!(priv.filter)
268
+ end
269
+ end
270
+
271
+ def privilege_fields
272
+ return {} unless PrivilegeService.current
273
+ PrivilegeService.current.get_privileges(self.privileges).each_with_object({}) do |priv, fields|
274
+ fields.merge!(priv.fields)
275
+ end
276
+ end
277
+ end
236
278
  end
237
279
 
238
280
  def type_validator(type)
@@ -278,5 +320,13 @@ module Menilite
278
320
  @listeners[event][field_name] ||= []
279
321
  @listeners[event][field_name] << block
280
322
  end
323
+
324
+ def resolve_references(key, value)
325
+ if self.class.field_info.has_key?(key.to_s) && self.class.field_info[key.to_s].type == :reference
326
+ ["#{key}_id".to_sym, value.id]
327
+ else
328
+ [key, value]
329
+ end
330
+ end
281
331
  end
282
332
  end
@@ -0,0 +1,36 @@
1
+ module Menilite
2
+ class Privilege
3
+ def key
4
+ raise NotImplementedError.new "Menilite::Privilege#key must be overriden"
5
+ end
6
+
7
+ def filter
8
+ {}
9
+ end
10
+
11
+ def fields
12
+ {}
13
+ end
14
+ end
15
+
16
+ class PrivilegeService
17
+ attr_reader :privileges
18
+
19
+ def initialize
20
+ @privileges = []
21
+ end
22
+
23
+ def self.init
24
+ instance = PrivilegeService.new
25
+ Thread.current.thread_variable_set(:previlege_service, instance)
26
+ end
27
+
28
+ def self.current
29
+ Thread.current.thread_variable_get(:previlege_service)
30
+ end
31
+
32
+ def get_privileges(names)
33
+ names.map{|key| @privileges.find{|p| p.key == key } }.compact
34
+ end
35
+ end
36
+ end
@@ -3,11 +3,11 @@ require 'sinatra/json'
3
3
  require 'json'
4
4
 
5
5
  class Class
6
- def subclass_of?(klass)
7
- raise ArgumentError.new unless klass.is_a?(Class)
6
+ def subclass_of?(klass, include_self = true)
7
+ raise ArgumentError.new unless klass.is_a?(Module)
8
8
 
9
9
  if self == klass
10
- true
10
+ include_self
11
11
  else
12
12
  if self.superclass
13
13
  self.superclass.subclass_of?(klass)
@@ -20,15 +20,30 @@ end
20
20
 
21
21
  module Menilite
22
22
  class Router
23
- def initialize(*classes)
24
- @classes = classes
23
+ def initialize
24
+ @classes = []
25
+
26
+ ObjectSpace.each_object(Class) do |klass|
27
+ @classes << klass if klass.subclass_of?(Menilite::Model, false)
28
+ @classes << klass if klass.subclass_of?(Menilite::Controller, false)
29
+ @classes << klass if klass.subclass_of?(Menilite::Privilege, false)
30
+ end
25
31
  end
26
32
 
27
33
  def before_action_handlers(klass, action)
28
34
  @handlers ||= @classes.select{|c| c.subclass_of?(Menilite::Controller) }.map{|c| c.before_action_handlers }.flatten
29
- @handlers.reject do |c|
30
- [c[:options][:expect]].flatten.any? do |expect|
31
- (classname, _, name) = expect.to_s.partition(?#)
35
+
36
+ handlers = @handlers.select do |c|
37
+ next true unless c[:options].has_key?(:include)
38
+ [c[:options][:include]].flatten.any? do |includes|
39
+ (classname, _, name) = includes.to_s.partition(?#)
40
+ (classname == klass.name) && (name.empty? || name == action.to_s)
41
+ end
42
+ end
43
+
44
+ handlers.reject do |c|
45
+ [c[:options][:exclude]].flatten.any? do |exclude|
46
+ (classname, _, name) = exclude.to_s.partition(?#)
32
47
  (classname == klass.name) && (name.empty? || name == action.to_s)
33
48
  end
34
49
  end
@@ -46,6 +61,7 @@ module Menilite
46
61
  klass.init
47
62
  resource_name = klass.name
48
63
  get "/#{resource_name}" do
64
+ PrivilegeService.init
49
65
  router.before_action_handlers(klass, 'index').each {|h| self.instance_eval(&h[:proc]) }
50
66
  order = params.delete('order')&.split(?,)
51
67
  data = klass.fetch(filter: params, order: order)
@@ -53,11 +69,13 @@ module Menilite
53
69
  end
54
70
 
55
71
  get "/#{resource_name}/:id" do
72
+ PrivilegeService.init
56
73
  router.before_action_handlers(klass, 'get').each {|h| self.instance_eval(&h[:proc]) }
57
74
  json klass[params[:id]].to_h
58
75
  end
59
76
 
60
77
  post "/#{resource_name}" do
78
+ PrivilegeService.init
61
79
  router.before_action_handlers(klass, 'post').each {|h| self.instance_eval(&h[:proc]) }
62
80
  data = JSON.parse(request.body.read)
63
81
  results = data.map do |model|
@@ -73,6 +91,7 @@ module Menilite
73
91
  path = action.options[:on_create] || action.options[:class] ? "/#{resource_name}/#{action.name}" : "/#{resource_name}/#{action.name}/:id"
74
92
 
75
93
  post path do
94
+ PrivilegeService.init
76
95
  router.before_action_handlers(klass, action.name).each {|h| self.instance_eval(&h[:proc]) }
77
96
  data = JSON.parse(request.body.read)
78
97
  result = if action.options[:on_create]
@@ -89,6 +108,7 @@ module Menilite
89
108
  klass.action_info.each do |name, action|
90
109
  path = klass.respond_to?(:namespace) ? "/#{klass.namespace}/#{action.name}" : "/#{action.name}"
91
110
  post path do
111
+ PrivilegeService.init
92
112
  router.before_action_handlers(klass, action.name).each {|h| self.instance_eval(&h[:proc]) }
93
113
  data = JSON.parse(request.body.read)
94
114
  controller = klass.new(session, settings)
@@ -1,3 +1,3 @@
1
1
  module Menilite
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: menilite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - youchan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-28 00:00:00.000000000 Z
11
+ date: 2016-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -85,7 +85,9 @@ files:
85
85
  - lib/menilite.rb
86
86
  - lib/menilite/client/store.rb
87
87
  - lib/menilite/controller.rb
88
+ - lib/menilite/helper.rb
88
89
  - lib/menilite/model.rb
90
+ - lib/menilite/privilege.rb
89
91
  - lib/menilite/router.rb
90
92
  - lib/menilite/server/activerecord_store.rb
91
93
  - lib/menilite/server/store.rb