flame 3.4.0 → 3.5.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: 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