flame 3.4.0 → 3.5.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: e91ac518b94afb516a97c8ed22a63c7e6381dc0e
4
- data.tar.gz: 187942692b4872a65869011f43153275e6faff36
3
+ metadata.gz: edd8f37ca2180414b5428f5d5bbb5cf146daa356
4
+ data.tar.gz: 1f79bd46b74f82ac879c470dc2df4d59d2120adc
5
5
  SHA512:
6
- metadata.gz: 21d8513b6c528d7b3b576f7cab5aedfe51ddd66c8b18cf451a0f6049ca7ef5b974c4668732c46c29e9c42c7a14c8b18943908c2f9493cfedb273071aa0ad5f61
7
- data.tar.gz: b78b9c72ba68ad431d27877776814261c4b74fd9b1e5b5c14d75a055c5f96c02ce2652e317b5d4b9fc70df0f76ffd68d8223b6f2e63692c5381e97d3309918e5
6
+ metadata.gz: 907034532dbbd46fad3ecb8963579a4ec92f161b0aad1c798a663aea55b46e38efa1b6a4e549d6a1706b5cd42973fb130878ac7b56d96e491ff0e027ec742a87
7
+ data.tar.gz: 19b1337d223b707b2ed27b692d718746f895fc7d439ee3bf296742889dcc19525ffe49b1f5a46943b2cadeb6e5d285d82bb80ca7fb9cf703d46ec6a6e01d9340
@@ -1,5 +1,4 @@
1
1
  require_relative 'router'
2
- require_relative 'request'
3
2
  require_relative 'dispatcher'
4
3
 
5
4
  module Flame
@@ -25,22 +24,32 @@ module Flame
25
24
  )
26
25
  end
27
26
 
28
- def self.call(env)
29
- @app ||= new
30
- @app.call env
27
+ def initialize(app = nil)
28
+ @app = app
29
+ router.routes.map! do |route|
30
+ route[:hooks] = router.find_hooks(route)
31
+ route.freeze
32
+ end
33
+ router.freeze
31
34
  end
32
35
 
33
36
  ## Init function
34
37
  def call(env)
38
+ @app.call(env) if @app.respond_to? :call
35
39
  Flame::Dispatcher.new(self, env).run!
36
40
  end
37
41
 
42
+ def self.call(env)
43
+ @app ||= new
44
+ @app.call env
45
+ end
46
+
38
47
  def self.mount(ctrl, path = nil, &block)
39
48
  router.add_controller(ctrl, path, block)
40
49
  end
41
50
 
42
51
  def self.helpers(*modules)
43
- modules.empty? ? (@helpers ||= []) : @helpers = modules
52
+ modules.empty? ? (@helpers ||= []) : helpers.concat(modules).uniq!
44
53
  end
45
54
 
46
55
  ## Router for routing
@@ -48,6 +57,10 @@ module Flame
48
57
  @router ||= Flame::Router.new(self)
49
58
  end
50
59
 
60
+ def router
61
+ self.class.router
62
+ end
63
+
51
64
  def self.default_config_dirs(root_dir:)
52
65
  {
53
66
  root_dir: File.realpath(root_dir),
@@ -29,7 +29,7 @@ module Flame
29
29
  )
30
30
  template.render(cache: config[:environment] == 'production')
31
31
  end
32
- alias_method :render, :view
32
+ alias render view
33
33
 
34
34
  ## Helpers from Flame::Dispatcher
35
35
  def method_missing(m, *args, &block)
@@ -37,14 +37,14 @@ module Flame
37
37
  @dispatcher.send(m, *args, &block)
38
38
  end
39
39
 
40
- private
40
+ class << self
41
+ using GorillaPatch::StringExt
41
42
 
42
- using GorillaPatch::StringExt
43
-
44
- def self.default_path(last = false)
45
- (name.split('::').last.underscore.split('_') - %w(index controller ctrl))
46
- .join('/').split('/')
47
- .unshift(nil)[(last ? -1 : 0)..-1].join('/')
43
+ def default_path(last = false)
44
+ (name.split('::').last.underscore.split('_') - %w(index controller ctrl))
45
+ .join('/').split('/')
46
+ .unshift(nil)[(last ? -1 : 0)..-1].join('/')
47
+ end
48
48
  end
49
49
  end
50
50
  end
@@ -0,0 +1,18 @@
1
+ module Flame
2
+ ## Helper class for cookies
3
+ class Cookies
4
+ def initialize(request_cookies, response)
5
+ @request_cookies = request_cookies
6
+ @response = response
7
+ end
8
+
9
+ def [](key)
10
+ @request_cookies[key.to_s]
11
+ end
12
+
13
+ def []=(key, new_value)
14
+ return @response.delete_cookie(key.to_s, path: '/') if new_value.nil?
15
+ @response.set_cookie(key.to_s, value: new_value, path: '/')
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,10 @@
1
1
  require 'gorilla-patch/hash'
2
2
 
3
+ require_relative 'cookies'
4
+ require_relative 'request'
5
+ require_relative 'response'
6
+ require_relative 'static'
7
+
3
8
  module Flame
4
9
  ## Helpers for dispatch Flame::Application#call
5
10
  class Dispatcher
@@ -7,26 +12,28 @@ module Flame
7
12
 
8
13
  using GorillaPatch::HashExt
9
14
 
15
+ include Flame::Dispatcher::Static
16
+
10
17
  def initialize(app, env)
11
18
  @app = app
19
+ @env = env
12
20
  @request = Flame::Request.new(env)
13
- @response = Rack::Response.new
21
+ @response = Flame::Response.new
14
22
  end
15
23
 
16
24
  def run!
17
- body = catch :halt do
25
+ catch :halt do
18
26
  try_route ||
19
- try_static ||
20
- try_static(File.join(__dir__, '..', '..', 'public')) ||
21
- halt(404)
27
+ try_static ||
28
+ try_static(File.join(__dir__, '..', '..', 'public')) ||
29
+ try_error(404)
22
30
  end
23
- # p body
24
- response.write body
25
31
  response.finish
26
32
  end
27
33
 
28
34
  def status(value = nil)
29
35
  response.status ||= 200
36
+ response.headers['X-Cascade'] = 'pass' if value == 404
30
37
  value ? response.status = value : response.status
31
38
  end
32
39
 
@@ -53,26 +60,37 @@ module Flame
53
60
  path.empty? ? '/' : path
54
61
  end
55
62
 
56
- def halt(new_status, body = nil, new_headers = {})
57
- new_status.is_a?(String) ? (body = new_status) : (status new_status)
58
- response.headers.merge!(new_headers)
59
- # p response.body
60
- if body.nil? &&
61
- !Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status)
62
- body = Rack::Utils::HTTP_STATUS_CODES[status]
63
+ def halt(new_status = nil, body = nil, new_headers = {})
64
+ case new_status
65
+ when String then body = new_status
66
+ when Integer then status new_status
63
67
  end
64
- throw :halt, body
68
+ # new_status.is_a?(String) ? () : (status new_status)
69
+ body = default_body if body.nil? && response.body.empty?
70
+ response.body = body if body
71
+ response.headers.merge!(new_headers)
72
+ throw :halt
65
73
  end
66
74
 
67
75
  private
68
76
 
77
+ ## Generate default body of error page
78
+ def default_body
79
+ return if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status)
80
+ "<h1>#{Rack::Utils::HTTP_STATUS_CODES[status]}</h1>"
81
+ end
82
+
83
+ ## Find nearest route
84
+ def nearest_route_for_request
85
+ @app.router.find_nearest_route(request.path_parts)
86
+ end
87
+
69
88
  ## Find route and try execute it
70
89
  def try_route
71
90
  route = @app.class.router.find_route(
72
91
  method: request.http_method,
73
92
  path_parts: request.path_parts
74
93
  )
75
- # p route
76
94
  return nil unless route
77
95
  status 200
78
96
  params.merge!(route.arguments(request.path_parts))
@@ -81,67 +99,29 @@ module Flame
81
99
  end
82
100
 
83
101
  def execute_route(route)
84
- ctrl = route[:controller].new(self)
85
- route[:befores].each { |before| ctrl.send(before) }
86
- result = ctrl.send(route[:action], *route.arranged_params(params))
87
- route[:afters].each { |after| result = execute_after(ctrl, after, result) }
88
- result
89
- end
90
-
91
- def execute_after(ctrl, after, result)
92
- case after.class.to_s.to_sym
93
- when :Symbol, :String
94
- result = ctrl.send(after.to_sym, result)
95
- when :Proc
96
- ctrl.instance_exec(result, &after)
97
- else
98
- fail UnexpectedTypeOfAfterError.new(after, route)
99
- end
100
- result
101
- end
102
-
103
- ## Find static files and try return it
104
- def try_static(dir = config[:public_dir])
105
- file = File.join(dir, request.path_info)
106
- # p static_file
107
- return nil unless File.exist?(file) && File.file?(file)
108
- return_static(file)
109
- end
110
-
111
- def static_cached?(file_time)
112
- since = request.env['HTTP_IF_MODIFIED_SINCE']
113
- since && Time.httpdate(since).to_i >= file_time.to_i
114
- end
115
-
116
- def return_static(file)
117
- file_time = File.mtime(file)
118
- halt 304 if static_cached?(file_time)
119
- mime_type = Rack::Mime.mime_type(File.extname(file))
120
- response.headers.merge!(
121
- 'Content-Type' => mime_type,
122
- 'Last-Modified' => file_time.httpdate
123
- # 'Content-Disposition' => 'attachment;' \
124
- # "filename=\"#{File.basename(static_file)}\"",
125
- # 'Content-Length' => File.size?(static_file).to_s
126
- )
127
- halt 200, File.read(file)
128
- end
129
-
130
- ## Helper class for cookies
131
- class Cookies
132
- def initialize(request_cookies, response)
133
- @request_cookies = request_cookies
134
- @response = response
135
- end
136
-
137
- def [](key)
138
- @request_cookies[key.to_s]
139
- end
140
-
141
- def []=(key, new_value)
142
- return @response.delete_cookie(key.to_s, path: '/') if new_value.nil?
143
- @response.set_cookie(key.to_s, value: new_value, path: '/')
144
- end
102
+ exec_route = route.executable
103
+ response.body = exec_route.run!(self)
104
+ rescue => exception
105
+ dump_error(exception)
106
+ # status 500
107
+ # exec_route.execute_errors(status)
108
+ try_error(500, exec_route)
109
+ end
110
+
111
+ def try_error(error_status = nil, exec_route = nil)
112
+ exec_route = nearest_route_for_request.executable unless exec_route
113
+ status error_status if error_status
114
+ exec_route.execute_errors(status)
115
+ halt
116
+ end
117
+
118
+ def dump_error(error)
119
+ msg = [
120
+ "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} - " \
121
+ "#{error.class} - #{error.message}:",
122
+ *error.backtrace
123
+ ].join("\n\t")
124
+ @env['rack.errors'].puts(msg)
145
125
  end
146
126
  end
147
127
  end
@@ -79,14 +79,14 @@ module Flame
79
79
  end
80
80
 
81
81
  ## Error for Flame::Router.find_path
82
- class UnexpectedTypeOfAfterError < StandardError
83
- def initialize(after, route)
84
- @after = after
82
+ class UnexpectedTypeOfHookError < StandardError
83
+ def initialize(hook, route)
84
+ @hook = hook
85
85
  @route = route
86
86
  end
87
87
 
88
88
  def message
89
- "Unexpected after-block class '#{@after.class}'" \
89
+ "Unexpected hook-block class '#{@hook.class}'" \
90
90
  " in route '#{@route}'"
91
91
  end
92
92
  end
@@ -16,6 +16,7 @@ module Flame
16
16
  @locals = options.merge(options.delete(:locals) || {})
17
17
  ## Find filename
18
18
  @filename = find_file(path)
19
+ @ctrl.instance_exec { halt 404 } unless @filename
19
20
  @layout = nil if File.basename(@filename)[0] == '_'
20
21
  end
21
22
 
@@ -26,7 +27,15 @@ module Flame
26
27
  layout_render tilt.render(@scope, @locals), cache: cache
27
28
  end
28
29
 
29
- private
30
+ private
31
+
32
+ class << self
33
+ private
34
+
35
+ def tilts
36
+ @tilts ||= {}
37
+ end
38
+ end
30
39
 
31
40
  using GorillaPatch::StringExt
32
41
 
@@ -34,19 +43,20 @@ module Flame
34
43
  Tilt.new(filename)
35
44
  end
36
45
 
37
- def self.tilts
38
- @tilts ||= {}
39
- end
40
-
41
46
  ## TODO: Add `views_dir` for Application and Controller
42
47
  ## TODO: Add `layout` method for Controller
43
48
  def find_file(path)
44
49
  ## Get full filename
50
+ # p Dir[File.join(
51
+ # @ctrl.config[:views_dir],
52
+ # "{#{controller_dirs.join(',')},}",
53
+ # "#{path}.*"
54
+ # )].uniq
45
55
  Dir[File.join(
46
56
  @ctrl.config[:views_dir],
47
57
  "{#{controller_dirs.join(',')},}",
48
58
  "#{path}.*"
49
- )].find do |file|
59
+ )].uniq.find do |file|
50
60
  Tilt[file]
51
61
  end
52
62
  end
@@ -68,11 +78,11 @@ module Flame
68
78
  ## Compile layout to hash
69
79
  return result unless layout_file
70
80
  layout =
71
- if cache
72
- self.class.tilts[layout_file] ||= compile(layout_file)
73
- else
74
- compile(layout_file)
75
- end
81
+ if cache
82
+ self.class.tilts[layout_file] ||= compile(layout_file)
83
+ else
84
+ compile(layout_file)
85
+ end
76
86
  return result unless layout
77
87
  layout.render(@scope, @locals) { result }
78
88
  end
@@ -0,0 +1,11 @@
1
+ module Flame
2
+ ## Class for responses
3
+ class Response < Rack::Response
4
+ ## Rewrite body assign (reset Content-Length and use #write)
5
+ def body=(value)
6
+ @length = 0
7
+ body.clear
8
+ write value
9
+ end
10
+ end
11
+ end
@@ -9,13 +9,17 @@ module Flame
9
9
  )
10
10
  end
11
11
 
12
- def [](attribute)
13
- @attributes[attribute]
12
+ def [](key)
13
+ @attributes[key]
14
14
  end
15
15
 
16
- def merge(attrs)
17
- dup.attributes.merge!(attrs)
18
- self
16
+ def []=(key, value)
17
+ @attributes[key] = value
18
+ end
19
+
20
+ ## Create Executable object (route)
21
+ def executable
22
+ Executable.new(self)
19
23
  end
20
24
 
21
25
  ## Compare attributes for `Router.find_route`
@@ -46,16 +50,6 @@ module Flame
46
50
  end
47
51
  end
48
52
 
49
- ## Arguments in order as parameters of method of controller
50
- def arranged_params(params)
51
- self[:controller].instance_method(self[:action]).parameters
52
- .each_with_object([]) do |par, arr|
53
- arr << params[par[1]] if par[0] == :req || params[par[1]]
54
- end
55
- end
56
-
57
- private
58
-
59
53
  ## Helpers for `compare_attributes`
60
54
  def compare_attribute(name, value)
61
55
  case name
@@ -99,5 +93,59 @@ module Flame
99
93
  ## All is ok
100
94
  param
101
95
  end
96
+
97
+ ## Class for Route execution
98
+ class Executable
99
+ def initialize(route)
100
+ @route = route
101
+ end
102
+
103
+ ## Execute route from Dispatcher
104
+ def run!(dispatcher)
105
+ @ctrl = @route[:controller].new(dispatcher)
106
+ execute_hooks(:before)
107
+ result = @ctrl.send(@route[:action], *arranged_params)
108
+ execute_hooks(:after)
109
+ result
110
+ end
111
+
112
+ def execute_errors(status = 500)
113
+ execute_hooks(:error, status)
114
+ end
115
+
116
+ private
117
+
118
+ ## Arguments in order as parameters of method of controller
119
+ def arranged_params
120
+ # action_parameters.each_with_object([]) do |par, arr|
121
+ # arr << @ctrl.params[par[1]] if par[0] == :req || @ctrl.params[par[1]]
122
+ # end
123
+ @ctrl.params.values_at(*action_parameters.map { |par| par[1] })
124
+ end
125
+
126
+ ## Method parameters of route controller#action
127
+ def action_parameters
128
+ @route[:controller].instance_method(@route[:action]).parameters
129
+ end
130
+
131
+ ## Execute before, after or error hook of Symbol, String or Proc
132
+ def execute_hook(hook)
133
+ case hook
134
+ when Symbol, String
135
+ @ctrl.send(hook.to_sym)
136
+ when Proc
137
+ @ctrl.instance_exec(&hook)
138
+ else
139
+ fail UnexpectedTypeOfHookError.new(hook, @route)
140
+ end
141
+ end
142
+
143
+ ## Execute before, after or error hooks
144
+ def execute_hooks(*keys)
145
+ hooks = @route[:hooks].dig(*keys)
146
+ # p hooks
147
+ hooks.each { |hook| execute_hook(hook) } if hooks
148
+ end
149
+ end
102
150
  end
103
151
  end
@@ -4,12 +4,12 @@ require_relative 'validators'
4
4
  module Flame
5
5
  ## Router class for routing
6
6
  class Router
7
- attr_reader :app, :routes, :befores, :afters
7
+ attr_reader :app, :routes, :hooks
8
8
 
9
9
  def initialize(app)
10
10
  @app = app
11
11
  @routes = []
12
- @befores, @afters = Array.new(2) { {} }
12
+ @hooks = {}
13
13
  end
14
14
 
15
15
  def add_controller(ctrl, path, block = nil)
@@ -22,39 +22,48 @@ module Flame
22
22
  end
23
23
 
24
24
  ## Find route by any attributes
25
- def find_route(attrs, with_hooks = true)
25
+ def find_route(attrs)
26
26
  route = routes.find { |r| r.compare_attributes(attrs) }
27
- return route unless route && with_hooks
28
- route.merge(
29
- befores: find_befores(route),
30
- afters: find_afters(route)
31
- )
27
+ route.dup if route
32
28
  end
33
29
 
34
- ## Find before hook by Route
35
- def find_befores(route)
36
- (befores[route[:controller]][:*] || []) +
37
- (befores[route[:controller]][route[:action]] || [])
30
+ ## Find the nearest route by path parts
31
+ def find_nearest_route(path_parts)
32
+ while path_parts.size >= 0
33
+ route = find_route(path_parts: path_parts)
34
+ break if route || path_parts.empty?
35
+ path_parts.pop
36
+ end
37
+ route
38
38
  end
39
39
 
40
- ## Find after hook by Route
41
- def find_afters(route)
42
- (afters[route[:controller]][:*] || []) +
43
- (afters[route[:controller]][route[:action]] || [])
40
+ ## Find hooks by Route
41
+ def find_hooks(route)
42
+ result = {}
43
+ hooks[route[:controller]].each do |type, hash|
44
+ if type == :error
45
+ result[type] = hash
46
+ else
47
+ result[type] = (hash[route[:action]] || []) | (hash[:*] || [])
48
+ end
49
+ end
50
+ # p result
51
+ result
44
52
  end
45
53
 
46
54
  private
47
55
 
48
56
  def concat_routes(route_refine)
49
57
  routes.concat(route_refine.routes)
50
- befores[route_refine.ctrl] = route_refine.befores
51
- afters[route_refine.ctrl] = route_refine.afters
58
+ hooks[route_refine.ctrl] = route_refine.hooks
52
59
  end
53
60
 
54
61
  ## Helper module for routing refine
55
62
  class RouteRefine
56
63
  attr_accessor :rest_routes
57
- attr_reader :ctrl, :routes, :befores, :afters
64
+ attr_reader :ctrl, :routes, :hooks
65
+
66
+ HOOK_TYPES = [:before, :after, :error].freeze
58
67
 
59
68
  def self.http_methods
60
69
  [:GET, :POST, :PUT, :DELETE]
@@ -75,7 +84,7 @@ module Flame
75
84
  @ctrl = ctrl
76
85
  @path = path || @ctrl.default_path
77
86
  @routes = []
78
- @befores, @afters = Array.new(2) { {} }
87
+ @hooks = HOOK_TYPES.each_with_object({}) { |type, hash| hash[type] = {} }
79
88
  execute(&block)
80
89
  end
81
90
 
@@ -90,14 +99,12 @@ module Flame
90
99
  end
91
100
  end
92
101
 
93
- def before(actions = :*, action = nil, &block)
94
- actions = [actions] unless actions.is_a?(Array)
95
- actions.each { |a| (@befores[a] ||= []).push(action || block) }
96
- end
97
-
98
- def after(actions = :*, action = nil, &block)
99
- actions = [actions] unless actions.is_a?(Array)
100
- actions.each { |a| (@afters[a] ||= []).push(action || block) }
102
+ HOOK_TYPES.each do |type|
103
+ default_actions = (type == :error ? 500 : :*)
104
+ define_method(type) do |actions = default_actions, action = nil, &block|
105
+ actions = [actions] unless actions.is_a?(Array)
106
+ actions.each { |a| (@hooks[type][a] ||= []).push(action || block) }
107
+ end
101
108
  end
102
109
 
103
110
  def defaults
@@ -141,10 +148,9 @@ module Flame
141
148
  ## TODO: Add :arg:type support (:id:num, :name:str, etc.)
142
149
  unshifted = force_params ? path : action_path(action)
143
150
  if path.nil? || force_params
144
- path = @ctrl.instance_method(action).parameters
145
- .map { |par| ":#{par[0] == :req ? '' : '?'}#{par[1]}" }
146
- .unshift(unshifted)
147
- .join('/')
151
+ parameters = @ctrl.instance_method(action).parameters
152
+ parameters.map! { |par| ":#{par[0] == :req ? '' : '?'}#{par[1]}" }
153
+ path = parameters.unshift(unshifted).join('/')
148
154
  end
149
155
  path_merge(@path, path)
150
156
  end
@@ -0,0 +1,32 @@
1
+ module Flame
2
+ class Dispatcher
3
+ ## Module for working with static files
4
+ module Static
5
+ ## Find static files and try return it
6
+ def try_static(dir = config[:public_dir])
7
+ file = File.join(dir, request.path_info)
8
+ return nil unless File.exist?(file) && File.file?(file)
9
+ return_static(file)
10
+ end
11
+
12
+ def static_cached?(file_time)
13
+ since = request.env['HTTP_IF_MODIFIED_SINCE']
14
+ since && Time.httpdate(since).to_i >= file_time.to_i
15
+ end
16
+
17
+ def return_static(file)
18
+ file_time = File.mtime(file)
19
+ halt 304 if static_cached?(file_time)
20
+ mime_type = Rack::Mime.mime_type(File.extname(file))
21
+ response.headers.merge!(
22
+ 'Content-Type' => mime_type,
23
+ 'Last-Modified' => file_time.httpdate
24
+ # 'Content-Disposition' => 'attachment;' \
25
+ # "filename=\"#{File.basename(static_file)}\"",
26
+ # 'Content-Length' => File.size?(static_file).to_s
27
+ )
28
+ halt 200, File.read(file)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -58,28 +58,42 @@ module Flame
58
58
  ## Compare actions from routes and from controller
59
59
  class ActionsValidator
60
60
  def initialize(route_refine)
61
- @routes = route_refine.routes
61
+ @routes_actions = route_refine.routes.map { |route| route[:action] }
62
+ @hooks_actions = route_refine.hooks.values.map(&:values).flatten
63
+ @hooks_actions.select! { |action| action.is_a? Symbol }
62
64
  @ctrl = route_refine.ctrl
65
+ @ctrl_actions = {
66
+ public: @ctrl.public_instance_methods(false),
67
+ all: @ctrl.instance_methods + @ctrl.private_instance_methods
68
+ }
63
69
  end
64
70
 
65
71
  def valid?
66
- @routes_actions = @routes.map { |route| route[:action] }
67
- @ctrl_actions = @ctrl.public_instance_methods(false)
68
- no_extra_routes_actions? && no_extra_controller_actions?
72
+ no_extra_routes_actions? &&
73
+ no_extra_hooks_actions? &&
74
+ no_extra_controller_actions?
69
75
  end
70
76
 
71
77
  private
72
78
 
73
79
  def no_extra_routes_actions?
74
- extra_routes_actions = @routes_actions - @ctrl_actions
80
+ extra_routes_actions = @routes_actions - @ctrl_actions[:public]
75
81
  return true if extra_routes_actions.empty?
76
82
  fail RouterError::ExtraRoutesActionsError.new(
77
83
  @ctrl, extra_routes_actions
78
84
  )
79
85
  end
80
86
 
87
+ def no_extra_hooks_actions?
88
+ extra_hooks_actions = @hooks_actions - @ctrl_actions[:all]
89
+ return true if extra_hooks_actions.empty?
90
+ fail RouterError::ExtraRoutesActionsError.new(
91
+ @ctrl, extra_hooks_actions
92
+ )
93
+ end
94
+
81
95
  def no_extra_controller_actions?
82
- extra_ctrl_actions = @ctrl_actions - @routes_actions
96
+ extra_ctrl_actions = @ctrl_actions[:public] - @routes_actions
83
97
  return true if extra_ctrl_actions.empty?
84
98
  fail RouterError::ExtraControllerActionsError.new(
85
99
  @ctrl, extra_ctrl_actions
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flame
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Popov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2016-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -75,12 +75,15 @@ files:
75
75
  - lib/flame.rb
76
76
  - lib/flame/application.rb
77
77
  - lib/flame/controller.rb
78
+ - lib/flame/cookies.rb
78
79
  - lib/flame/dispatcher.rb
79
80
  - lib/flame/errors.rb
80
81
  - lib/flame/render.rb
81
82
  - lib/flame/request.rb
83
+ - lib/flame/response.rb
82
84
  - lib/flame/route.rb
83
85
  - lib/flame/router.rb
86
+ - lib/flame/static.rb
84
87
  - lib/flame/validators.rb
85
88
  - public/favicon.ico
86
89
  homepage: https://gitlab.com/AlexWayfer/flame