flame 3.6.2 → 4.0.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: d36bd7e8c5db7454423ff5a080c407aad30dd67e
4
- data.tar.gz: 604cd066e8145524a01d323f4c3e021445413722
3
+ metadata.gz: 3b164f4b1817723648efb5412dc308265aaa30af
4
+ data.tar.gz: dc130470827a1bb8f1c22689c605381aa97ee78d
5
5
  SHA512:
6
- metadata.gz: 4a6a22af1494cf9092ba01005e959579c93d900b6ce76d7bfb81dace1515649bf0f8b9d7bbd32b09f550120edbafeb789e71ec3a410b24aa7a9893d0692f5534
7
- data.tar.gz: 941cc3b8d7891810c44b7998592c7263ce4cf3325d654b9041e335474b2bf094446589d5abf104d304e2a3b5b758c4838b36c53822ff5ba2518f9cd211c64976
6
+ metadata.gz: 2a482215bfd58d3ca783ac1c904f171d5e09f5a2cd42245b6324bf433ffb8611827602e551099076939969fe07b23ae0defb1be6a1c68d18708a270b4b97e3f4
7
+ data.tar.gz: 5afe0a7dcd19b8ee8eb9d674211f456ea0232932fd40bc0e24f86837dce011d81216c9ecaba9ab84bd4f5cc263a1c813efd1be6a28ceba7febb60dda3ce3341e
@@ -13,6 +13,7 @@ module Flame
13
13
  self.class.config
14
14
  end
15
15
 
16
+ ## Generating application config when inherited
16
17
  def self.inherited(app)
17
18
  app.config = Config.new(
18
19
  app,
@@ -26,32 +27,38 @@ module Flame
26
27
 
27
28
  def initialize(app = nil)
28
29
  @app = app
29
- router.routes.map! do |route|
30
- route[:hooks] = router.find_hooks(route)
31
- route.freeze
32
- end
33
- router.freeze
34
30
  end
35
31
 
36
- ## Init function
32
+ ## Request recieving method
37
33
  def call(env)
38
34
  @app.call(env) if @app.respond_to? :call
39
35
  Flame::Dispatcher.new(self, env).run!
40
36
  end
41
37
 
38
+ ## Make available `run Application` without `.new` for `rackup`
42
39
  def self.call(env)
43
40
  @app ||= new
44
41
  @app.call env
45
42
  end
46
43
 
44
+ ## Mount controller in application class
45
+ ## @param ctrl [Flame::Controller] the mounted controller class
46
+ ## @param path [String, nil] root path for the mounted controller
47
+ ## @yield refine defaults pathes for a methods of the mounted controller
48
+ ## @example Mount controller with defaults
49
+ ## mount ArticlesController
50
+ ## @example Mount controller with specific path
51
+ ## mount HomeController, '/welcome'
52
+ ## @example Mount controller with specific path of methods
53
+ ## mount HomeController do
54
+ ## get '/bye', :goodbye
55
+ ## post '/greetings', :new
56
+ ## defaults
57
+ ## end
47
58
  def self.mount(ctrl, path = nil, &block)
48
59
  router.add_controller(ctrl, path, block)
49
60
  end
50
61
 
51
- def self.helpers(*modules)
52
- modules.empty? ? (@helpers ||= []) : helpers.concat(modules).uniq!
53
- end
54
-
55
62
  ## Router for routing
56
63
  def self.router
57
64
  @router ||= Flame::Router.new(self)
@@ -61,6 +68,7 @@ module Flame
61
68
  self.class.router
62
69
  end
63
70
 
71
+ ## Initialize default for config directories
64
72
  def self.default_config_dirs(root_dir:)
65
73
  {
66
74
  root_dir: File.realpath(root_dir),
@@ -5,6 +5,8 @@ module Flame
5
5
  ## Class initialize when Dispatcher found route with it
6
6
  ## For new request and response
7
7
  class Controller
8
+ ## Initialize the controller for request execution
9
+ ## @param dispatcher [Flame::Dispatcher] dispatcher object
8
10
  def initialize(dispatcher)
9
11
  @dispatcher = dispatcher
10
12
  end
@@ -15,12 +17,27 @@ module Flame
15
17
  @dispatcher.path_to(*args)
16
18
  end
17
19
 
20
+ ## Redirect for response
21
+ ## @overload redirect(path)
22
+ ## Redirect to the string path
23
+ ## @param path [String] path
24
+ ## @example Redirect to '/hello'
25
+ ## redirect '/hello'
26
+ ## @overload redirect(*args)
27
+ ## Redirect to the path of `path_to` method
28
+ ## @param args arguments for `path_to` method
29
+ ## @example Redirect to `show` method of `ArticlesController` with id = 2
30
+ ## redirect ArticlesController, :show, id: 2
18
31
  def redirect(*params)
19
32
  response.redirect(
20
33
  params[0].is_a?(String) ? params[0] : path_to(*params)
21
34
  )
22
35
  end
23
36
 
37
+ ## Render a template with `Flame::Render` (based on Tilt-engine)
38
+ ## @param path [Symbol, nil] path to the template file
39
+ ## @param options [Hash] options for the `Flame::Render` rendering
40
+ ## @return [String] rendered template
24
41
  def view(path = nil, options = {})
25
42
  template = Flame::Render.new(
26
43
  self,
@@ -31,7 +48,26 @@ module Flame
31
48
  end
32
49
  alias render view
33
50
 
34
- ## Helpers from Flame::Dispatcher
51
+ ## Execute the method of the controller with hooks (may be overloaded)
52
+ ## @param method [Symbol] name of the controller method
53
+ def execute(method)
54
+ # send method
55
+ body send(
56
+ method,
57
+ *params.values_at(
58
+ *self.class.instance_method(method).parameters.map { |par| par[1] }
59
+ )
60
+ )
61
+ rescue => exception
62
+ # p 'rescue from controller'
63
+ status 500
64
+ dump_error(exception)
65
+
66
+ ## Re-raise exception for inherited controllers or `Flame::Dispatcher`
67
+ raise exception
68
+ end
69
+
70
+ ## Call helpers methods from `Flame::Dispatcher`
35
71
  def method_missing(m, *args, &block)
36
72
  return super unless @dispatcher.respond_to?(m)
37
73
  @dispatcher.send(m, *args, &block)
@@ -40,6 +76,7 @@ module Flame
40
76
  class << self
41
77
  using GorillaPatch::StringExt
42
78
 
79
+ ## Default root path of the controller for requests
43
80
  def default_path(last = false)
44
81
  (name.split('::').last.underscore.split('_') - %w(index controller ctrl))
45
82
  .join('/').split('/')
data/lib/flame/cookies.rb CHANGED
@@ -6,10 +6,19 @@ module Flame
6
6
  @response = response
7
7
  end
8
8
 
9
+ ## Get request cookies
10
+ ## @param key [String, Symbol] name of cookie
9
11
  def [](key)
10
12
  @request_cookies[key.to_s]
11
13
  end
12
14
 
15
+ ## Set (or delete) cookies for response
16
+ ## @param key [String, Symbol] name of cookie
17
+ ## @param new_value [Object, nil] value of cookie
18
+ ## @example Set new value to `cat` cookie
19
+ ## cookies['cat'] = 'nice cat'
20
+ ## @example Delete `cat` cookie
21
+ ## cookies['cat'] = nil
13
22
  def []=(key, new_value)
14
23
  return @response.delete_cookie(key.to_s, path: '/') if new_value.nil?
15
24
  @response.set_cookie(key.to_s, value: new_value, path: '/')
@@ -14,6 +14,9 @@ module Flame
14
14
 
15
15
  include Flame::Dispatcher::Static
16
16
 
17
+ ## Initialize Dispatcher from Application#call
18
+ ## @param app [Flame::Application] application object
19
+ ## @param env Rack-environment object
17
20
  def initialize(app, env)
18
21
  @app = app
19
22
  @env = env
@@ -21,43 +24,66 @@ module Flame
21
24
  @response = Flame::Response.new
22
25
  end
23
26
 
27
+ ## Start of execution the request
24
28
  def run!
25
29
  catch :halt do
26
30
  try_route ||
27
31
  try_static ||
28
32
  try_static(File.join(__dir__, '..', '..', 'public')) ||
29
- try_error(404)
33
+ not_found
30
34
  end
31
35
  response.write body
32
36
  response.finish
33
37
  end
34
38
 
39
+ ## Acccess to the status of response
40
+ ## @param value [Ineger, nil] integer value for new status
41
+ ## @return [Integer] current status
42
+ ## @example Set status value
43
+ ## status 200
35
44
  def status(value = nil)
36
45
  response.status ||= 200
37
46
  response.headers['X-Cascade'] = 'pass' if value == 404
38
47
  value ? response.status = value : response.status
39
48
  end
40
49
 
50
+ ## Acccess to the body of response
51
+ ## @param value [String, nil] string value for new body
52
+ ## @return [String] current body
53
+ ## @example Set body value
54
+ ## body 'Hello World!'
41
55
  def body(value = nil)
42
56
  value ? @body = value : @body ||= ''
43
57
  end
44
58
 
59
+ ## Parameters of the request
45
60
  def params
46
61
  @params ||= request.params.merge(request.params.keys_to_sym)
47
62
  end
48
63
 
64
+ ## Session object as Hash
49
65
  def session
50
66
  request.session
51
67
  end
52
68
 
69
+ ## Cookies object as Hash
53
70
  def cookies
54
71
  @cookies ||= Cookies.new(request.cookies, response)
55
72
  end
56
73
 
74
+ ## Application-config object as Hash
57
75
  def config
58
76
  @app.config
59
77
  end
60
78
 
79
+ ## Get path for controller and action.
80
+ ##
81
+ ## @param ctrl [Flame::Controller] class of controller
82
+ ## @param action [Symbol] method of controller
83
+ ## @param args [Hash] parameters for method of controller
84
+ ## @return [String] path for requested method, controller and parameters
85
+ ## @example Path for `show(id)` method of `ArticlesController` with `id: 2`
86
+ ## path_to ArticlesController, :show, id: 2 # => "/articles/show/2"
61
87
  def path_to(ctrl, action = :index, args = {})
62
88
  route = @app.class.router.find_route(controller: ctrl, action: action)
63
89
  fail RouteNotFoundError.new(ctrl, action) unless route
@@ -65,10 +91,22 @@ module Flame
65
91
  path.empty? ? '/' : path
66
92
  end
67
93
 
68
- def halt(new_status = nil, new_body = nil, new_headers = {})
69
- case new_status
70
- when String then new_body = new_status
71
- when Integer then status new_status
94
+ ## Interrupt the execution of route, and set new optional data
95
+ ## (otherwise using existing)
96
+ ## @param new_status_or_body [Integer, String]
97
+ ## set new HTTP status code or new body
98
+ ## @param new_body [String] set new body
99
+ ## @param new_headers [String] merge new headers
100
+ ## @example Halt with 500, no change body
101
+ ## halt 500
102
+ ## @example Halt with 404, render template
103
+ ## halt 404, render('errors/404')
104
+ ## @example Halt with 200, set new headers
105
+ ## halt 200, 'Cats!', 'Content-Type' => 'animal/cat'
106
+ def halt(new_status_or_body = nil, new_body = nil, new_headers = {})
107
+ case new_status_or_body
108
+ when String then new_body = new_status_or_body
109
+ when Integer then status new_status_or_body
72
110
  end
73
111
  # new_status.is_a?(String) ? () : (status new_status)
74
112
  new_body = default_body if new_body.nil? && body.empty?
@@ -77,20 +115,27 @@ module Flame
77
115
  throw :halt
78
116
  end
79
117
 
118
+ ## Add error's backtrace to @env['rack.errors'] (terminal or file)
119
+ ## @param error [Exception] exception for class, message and backtrace
120
+ def dump_error(error)
121
+ msg = [
122
+ "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} - " \
123
+ "#{error.class} - #{error.message}:",
124
+ *error.backtrace
125
+ ].join("\n\t")
126
+ @env['rack.errors'].puts(msg)
127
+ end
128
+
80
129
  private
81
130
 
82
131
  ## Generate default body of error page
83
132
  def default_body
133
+ ## Return nil if must be no body for current HTTP status
84
134
  return if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status)
85
135
  response.headers[Rack::CONTENT_TYPE] = 'text/html'
86
136
  "<h1>#{Rack::Utils::HTTP_STATUS_CODES[status]}</h1>"
87
137
  end
88
138
 
89
- ## Find nearest route
90
- def nearest_route_for_request
91
- @app.router.find_nearest_route(request.path_parts)
92
- end
93
-
94
139
  ## Find route and try execute it
95
140
  def try_route
96
141
  route = @app.class.router.find_route(
@@ -98,39 +143,36 @@ module Flame
98
143
  path_parts: request.path_parts
99
144
  )
100
145
  return nil unless route
101
- status 200
102
- params.merge!(route.arguments(request.path_parts))
103
- # route.execute(self)
104
146
  execute_route(route)
105
147
  end
106
148
 
149
+ ## Execute route
150
+ ## @param route [Flame::Route] route that must be executed
107
151
  def execute_route(route)
108
- exec_route = route.executable(self)
109
- exec_route.run!
110
- rescue => exception
111
- dump_error(exception)
112
- # status 500
113
- # exec_route.execute_errors(status)
114
- try_error(500, exec_route)
115
- end
116
-
117
- def try_error(error_status = nil, exec_route = nil)
118
- status error_status if error_status
119
- unless exec_route
120
- route = nearest_route_for_request unless exec_route
121
- exec_route = route.executable(self) if route
122
- end
123
- exec_route.execute_errors(status) if exec_route
124
- halt
125
- end
126
-
127
- def dump_error(error)
128
- msg = [
129
- "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} - " \
130
- "#{error.class} - #{error.message}:",
131
- *error.backtrace
132
- ].join("\n\t")
133
- @env['rack.errors'].puts(msg)
152
+ status 200
153
+ params.merge!(route.arguments(request.path_parts))
154
+ # route.execute(self)
155
+ route[:controller].new(self).execute(route[:action])
156
+ rescue => _exception
157
+ # p 'rescue from dispatcher'
158
+ halt 500
159
+
160
+ # p 're raise exception from dispatcher'
161
+ # raise exception
162
+ end
163
+
164
+ ## Generate a response if the route is not found
165
+ def not_found
166
+ # p 'not found from dispatcher'
167
+ ## Change the status of response to 404
168
+ status 404
169
+ ## Find the nearest route by the parts of requested path
170
+ route = @app.router.find_nearest_route(request.path_parts)
171
+ ## Halt with default body if the route not found
172
+ ## or it's `not_found` method not defined
173
+ return halt unless route && route[:controller].method_defined?(:not_found)
174
+ ## Execute `not_found` method for the founded route
175
+ route[:controller].new(self).execute(:not_found)
134
176
  end
135
177
  end
136
178
  end
data/lib/flame/render.rb CHANGED
@@ -20,6 +20,8 @@ module Flame
20
20
  @layout = nil if File.basename(@filename)[0] == '_'
21
21
  end
22
22
 
23
+ ## Render template
24
+ ## @param cache [Boolean] cache compiles or not
23
25
  def render(cache: true)
24
26
  ## Compile Tilt to instance hash
25
27
  tilt = cache ? self.class.tilts[@filename] ||= compile : compile
@@ -39,19 +41,16 @@ module Flame
39
41
 
40
42
  using GorillaPatch::StringExt
41
43
 
44
+ ## Compile file with Tilt engine
45
+ ## @param filename [String] filename
42
46
  def compile(filename = @filename)
43
47
  Tilt.new(filename)
44
48
  end
45
49
 
46
- ## TODO: Add `views_dir` for Application and Controller
47
- ## TODO: Add `layout` method for Controller
50
+ ## @todo Add `views_dir` for Application and Controller
51
+ ## @todo Add `layout` method for Controller
48
52
  def find_file(path)
49
53
  ## Get full filename
50
- # p Dir[File.join(
51
- # @ctrl.config[:views_dir],
52
- # "{#{controller_dirs.join(',')},}",
53
- # "#{path}.*"
54
- # )].uniq
55
54
  Dir[File.join(
56
55
  @ctrl.config[:views_dir],
57
56
  "{#{controller_dirs.join(',')},}",
@@ -61,18 +60,21 @@ module Flame
61
60
  end
62
61
  end
63
62
 
63
+ ## Find possible directories for the controller
64
64
  def controller_dirs
65
- ## Build controller_dirs
66
- controller_dir = (
67
- @ctrl.class.name.underscore.split('_') - %w(controller ctrl)
68
- ).join('_')
69
- controller_dir_parts = controller_dir.split('/')
65
+ controller_dir_parts = @ctrl.class.name.underscore.split('/').map do |part|
66
+ (part.split('_') - %w(controller controllers ctrl)).join('_')
67
+ end
68
+ controller_dir = controller_dir_parts.join('/')
70
69
  [controller_dir,
71
70
  controller_dir_parts[1..-1].join('/'),
72
71
  controller_dir_parts[1..-2].join('/'),
73
72
  controller_dir_parts.last]
74
73
  end
75
74
 
75
+ ## Render the layout with template
76
+ ## @param result [String] result of template rendering
77
+ ## @param cache [Boolean] cache compiles or not
76
78
  def layout_render(result, cache: true)
77
79
  layout_file = find_file(@layout)
78
80
  ## Compile layout to hash
data/lib/flame/request.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  module Flame
2
2
  ## Class for requests
3
3
  class Request < Rack::Request
4
+ ## Split path of the request to parts (Array of String)
4
5
  def path_parts
5
6
  @path_parts ||= path_info.to_s.split('/').reject(&:empty?)
6
7
  end
7
8
 
9
+ ## Override HTTP-method of the request if the param '_method' found
8
10
  def http_method
9
11
  params['_method'] || request_method
10
12
  end
data/lib/flame/route.rb CHANGED
@@ -5,24 +5,26 @@ module Flame
5
5
 
6
6
  def initialize(attrs = {})
7
7
  @attributes = attrs.merge(
8
- path_parts: attrs[:path].to_s.split('/').reject(&:empty?)
8
+ ## Split path to parts (Array of String)
9
+ path_parts: attrs[:path].to_s.split('/').reject(&:empty?).freeze
9
10
  )
10
11
  end
11
12
 
13
+ ## Get the attribute of route
14
+ ## @param key [Symbol] name of attribute
12
15
  def [](key)
13
16
  @attributes[key]
14
17
  end
15
18
 
19
+ ## Set the attribute of route
20
+ ## @param key [Symbol] name of attribute
21
+ ## @param value [Object] value of attribute
16
22
  def []=(key, value)
17
23
  @attributes[key] = value
18
24
  end
19
25
 
20
- ## Create Executable object (route)
21
- def executable(dispatcher)
22
- Executable.new(self, dispatcher)
23
- end
24
-
25
26
  ## Compare attributes for `Router.find_route`
27
+ ## @param attrs [Hash] Hash of attributes for comparing
26
28
  def compare_attributes(attrs)
27
29
  attrs.each do |name, value|
28
30
  next true if compare_attribute(name, value)
@@ -31,6 +33,7 @@ module Flame
31
33
  end
32
34
 
33
35
  ## Assign arguments to path for `Controller.path_to`
36
+ ## @param args [Hash] arguments for assigning
34
37
  def assign_arguments(args = {})
35
38
  self[:path_parts]
36
39
  .map { |path_part| assign_argument(path_part, args) }
@@ -38,6 +41,7 @@ module Flame
38
41
  end
39
42
 
40
43
  ## Extract arguments from request_parts for `execute`
44
+ ## @param request_parts [Array] parts of the request (Array of String)
41
45
  def arguments(request_parts)
42
46
  self[:path_parts].each_with_index.with_object({}) do |(path_part, i), args|
43
47
  request_part = request_parts[i]
@@ -93,59 +97,5 @@ module Flame
93
97
  ## All is ok
94
98
  param
95
99
  end
96
-
97
- ## Class for Route execution
98
- class Executable
99
- ## Create executable route with dispatcher
100
- def initialize(route, dispatcher)
101
- @route = route
102
- @ctrl = @route[:controller].new(dispatcher)
103
- end
104
-
105
- ## Execute route
106
- def run!
107
- execute_hooks(:before)
108
- @ctrl.body @ctrl.send(@route[:action], *arranged_params)
109
- execute_hooks(:after)
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
150
100
  end
151
101
  end
data/lib/flame/router.rb CHANGED
@@ -4,30 +4,36 @@ require_relative 'validators'
4
4
  module Flame
5
5
  ## Router class for routing
6
6
  class Router
7
- attr_reader :app, :routes, :hooks
7
+ attr_reader :app, :routes
8
8
 
9
9
  def initialize(app)
10
10
  @app = app
11
11
  @routes = []
12
- @hooks = {}
13
12
  end
14
13
 
14
+ ## Add the controller with it's methods to routes
15
+ ## @param ctrl [Flame::Controller] class of the controller which will be added
16
+ ## @param path [String] root path for controller's methods
17
+ ## @param block [Proc, nil] block for routes refine
15
18
  def add_controller(ctrl, path, block = nil)
16
- ## TODO: Add Regexp paths
19
+ ## @todo Add Regexp paths
17
20
 
18
21
  ## Add routes from controller to glob array
19
- ctrl.include(*@app.helpers)
20
22
  route_refine = RouteRefine.new(self, ctrl, path, block)
21
23
  concat_routes(route_refine) if ActionsValidator.new(route_refine).valid?
22
24
  end
23
25
 
24
26
  ## Find route by any attributes
27
+ ## @param attrs [Hash] attributes for comparing
28
+ ## @return [Flame::Route, nil] return the found route, otherwise `nil`
25
29
  def find_route(attrs)
26
30
  route = routes.find { |r| r.compare_attributes(attrs) }
27
31
  route.dup if route
28
32
  end
29
33
 
30
34
  ## Find the nearest route by path parts
35
+ ## @param path_parts [Array] parts of path for route finding
36
+ ## @return [Flame::Route, nil] return the found nearest route, otherwise `nil`
31
37
  def find_nearest_route(path_parts)
32
38
  while path_parts.size >= 0
33
39
  route = find_route(path_parts: path_parts)
@@ -37,38 +43,24 @@ module Flame
37
43
  route
38
44
  end
39
45
 
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
52
- end
53
-
54
46
  private
55
47
 
48
+ ## Add `RouteRefine` routes to the routes of `Flame::Router`
49
+ ## @param route_refine [Flame::Router::RouteRefine] `RouteRefine` with routes
56
50
  def concat_routes(route_refine)
57
51
  routes.concat(route_refine.routes)
58
- hooks[route_refine.ctrl] = route_refine.hooks
59
52
  end
60
53
 
61
- ## Helper module for routing refine
54
+ ## Helper class for controller routing refine
62
55
  class RouteRefine
63
56
  attr_accessor :rest_routes
64
- attr_reader :ctrl, :routes, :hooks
65
-
66
- HOOK_TYPES = [:before, :after, :error].freeze
57
+ attr_reader :ctrl, :routes
67
58
 
68
59
  def self.http_methods
69
60
  [:GET, :POST, :PUT, :DELETE]
70
61
  end
71
62
 
63
+ ## Defaults REST routes (methods, pathes, controllers actions)
72
64
  def rest_routes
73
65
  @rest_routes ||= [
74
66
  { method: :GET, path: '/', action: :index },
@@ -84,11 +76,22 @@ module Flame
84
76
  @ctrl = ctrl
85
77
  @path = path || @ctrl.default_path
86
78
  @routes = []
87
- @hooks = HOOK_TYPES.each_with_object({}) { |type, hash| hash[type] = {} }
88
79
  execute(&block)
89
80
  end
90
81
 
91
82
  http_methods.each do |request_method|
83
+ ## Define refine methods for all HTTP methods
84
+ ## @overload post(path, action)
85
+ ## Execute action on requested path and HTTP method
86
+ ## @param path [String] path of method for the request
87
+ ## @param action [Symbol] name of method for the request
88
+ ## @example Set path to '/bye' and method to :POST for action `goodbye`
89
+ ## post '/bye', :goodbye
90
+ ## @overload post(action)
91
+ ## Execute action on requested HTTP method
92
+ ## @param action [Symbol] name of method for the request
93
+ ## @example Set method to :POST for action `goodbye`
94
+ ## post :goodbye
92
95
  define_method(request_method.downcase) do |path, action = nil|
93
96
  if action.nil?
94
97
  action = path.to_sym
@@ -99,14 +102,8 @@ module Flame
99
102
  end
100
103
  end
101
104
 
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
108
- end
109
-
105
+ ## Assign remaining methods of the controller
106
+ ## to defaults pathes and HTTP methods
110
107
  def defaults
111
108
  rest
112
109
  @ctrl.public_instance_methods(false).each do |action|
@@ -115,6 +112,7 @@ module Flame
115
112
  end
116
113
  end
117
114
 
115
+ ## Assign methods of the controller to REST architecture
118
116
  def rest
119
117
  rest_routes.each do |rest_route|
120
118
  action = rest_route[:action]
@@ -125,6 +123,10 @@ module Flame
125
123
  end
126
124
  end
127
125
 
126
+ ## Mount controller inside other (parent) controller
127
+ ## @param ctrl [Flame::Controller] class of mounting controller
128
+ ## @param path [String, nil] root path for mounting controller
129
+ ## @yield Block of code for routes refine
128
130
  def mount(ctrl, path = nil, &block)
129
131
  path = path_merge(
130
132
  @path,
@@ -135,15 +137,18 @@ module Flame
135
137
 
136
138
  private
137
139
 
140
+ ## Execute block of refinings end sorting routes
138
141
  def execute(&block)
139
142
  block.nil? ? defaults : instance_exec(&block)
140
- @router.app.helpers.each do |helper|
141
- instance_exec(&helper.mount) if helper.respond_to?(:mount)
142
- end
143
+ # instance_exec(&@ctrl.mounted) if @ctrl.respond_to? :mounted
144
+ # @router.app.helpers.each do |helper|
145
+ # instance_exec(&helper.mount) if helper.respond_to?(:mount)
146
+ # end
143
147
  # p @routes
144
148
  @routes.sort! { |a, b| b[:path] <=> a[:path] }
145
149
  end
146
150
 
151
+ ## Build path for the action of controller
147
152
  def make_path(path, action = nil, force_params = false)
148
153
  ## TODO: Add :arg:type support (:id:num, :name:str, etc.)
149
154
  unshifted = force_params ? path : action_path(action)
@@ -59,8 +59,6 @@ module Flame
59
59
  class ActionsValidator
60
60
  def initialize(route_refine)
61
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 }
64
62
  @ctrl = route_refine.ctrl
65
63
  @ctrl_actions = {
66
64
  public: @ctrl.public_instance_methods(false),
@@ -69,9 +67,7 @@ module Flame
69
67
  end
70
68
 
71
69
  def valid?
72
- no_extra_routes_actions? &&
73
- no_extra_hooks_actions? &&
74
- no_extra_controller_actions?
70
+ no_extra_routes_actions? && no_extra_controller_actions?
75
71
  end
76
72
 
77
73
  private
@@ -84,14 +80,6 @@ module Flame
84
80
  )
85
81
  end
86
82
 
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
-
95
83
  def no_extra_controller_actions?
96
84
  extra_ctrl_actions = @ctrl_actions[:public] - @routes_actions
97
85
  return true if extra_ctrl_actions.empty?
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.6.2
4
+ version: 4.0.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-26 00:00:00.000000000 Z
11
+ date: 2016-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack