menilite 0.1.0 → 0.2.0

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 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