flame 4.0.0 → 4.0.1
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 +4 -4
- data/lib/flame/cookies.rb +23 -21
- data/lib/flame/errors.rb +71 -69
- data/lib/flame/route.rb +85 -83
- data/lib/flame/router.rb +7 -5
- data/lib/flame/validators.rb +75 -73
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 255a8d94f1326b67225cdd4b19f9f7e98de75bdd
|
4
|
+
data.tar.gz: 14d93ff6ae287e137c8711de646c38443583f333
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c4546180307af412902b9e1444bf36109c9071dcdf9cabaf828e43f2aba8c41bdbf99ea5ec5dc64e7be7647ab11204a7d76f9382d2868cc3b8f20d4f48c9215
|
7
|
+
data.tar.gz: d6c1a14007b6c072a2ad736237c13e90386c9e7397b5ba2471b7eb61f2a9761353ae06f00ec41245307ea44dcb662fffac654a3b10c3bf603413e7be4bc14251
|
data/lib/flame/cookies.rb
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
module Flame
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
class Dispatcher
|
3
|
+
## Helper class for cookies
|
4
|
+
class Cookies
|
5
|
+
def initialize(request_cookies, response)
|
6
|
+
@request_cookies = request_cookies
|
7
|
+
@response = response
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
## Get request cookies
|
11
|
+
## @param key [String, Symbol] name of cookie
|
12
|
+
def [](key)
|
13
|
+
@request_cookies[key.to_s]
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
## Set (or delete) cookies for response
|
17
|
+
## @param key [String, Symbol] name of cookie
|
18
|
+
## @param new_value [Object, nil] value of cookie
|
19
|
+
## @example Set new value to `cat` cookie
|
20
|
+
## cookies['cat'] = 'nice cat'
|
21
|
+
## @example Delete `cat` cookie
|
22
|
+
## cookies['cat'] = nil
|
23
|
+
def []=(key, new_value)
|
24
|
+
return @response.delete_cookie(key.to_s, path: '/') if new_value.nil?
|
25
|
+
@response.set_cookie(key.to_s, value: new_value, path: '/')
|
26
|
+
end
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
data/lib/flame/errors.rb
CHANGED
@@ -1,93 +1,95 @@
|
|
1
1
|
module Flame
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
module Errors
|
3
|
+
module RouterError
|
4
|
+
## Error for Flame::Router.compare_actions
|
5
|
+
class ActionsError < StandardError
|
6
|
+
def initialize(ctrl, extra_actions)
|
7
|
+
@ctrl = ctrl
|
8
|
+
@extra_actions = extra_actions
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
## Error if routes have more actions, than controller
|
13
|
+
class ExtraRoutesActionsError < ActionsError
|
14
|
+
def message
|
15
|
+
"Controller '#{@ctrl}' has no methods" \
|
16
|
+
" '#{@extra_actions.join(', ')}' from routes"
|
17
|
+
end
|
16
18
|
end
|
17
|
-
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
## Error if controller has not assigned in routes actions
|
21
|
+
class ExtraControllerActionsError < ActionsError
|
22
|
+
def message
|
23
|
+
"Routes for '#{@ctrl}' has no methods" \
|
24
|
+
" '#{@extra_actions.join(', ')}'"
|
25
|
+
end
|
24
26
|
end
|
25
|
-
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
## Error for Flame::Router::RouteRefine.arguments_valid?
|
29
|
+
class ArgumentsError < StandardError
|
30
|
+
def initialize(ctrl, action, path, extra_args)
|
31
|
+
@ctrl = ctrl
|
32
|
+
@action = action
|
33
|
+
@path = path
|
34
|
+
@extra_args = extra_args
|
35
|
+
end
|
34
36
|
end
|
35
|
-
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
## Error if path has more arguments, than controller's method
|
39
|
+
class ExtraPathArgumentsError < ArgumentsError
|
40
|
+
def message
|
41
|
+
"Method '#{@action}' from controller '#{@ctrl}'" \
|
42
|
+
" does not know arguments '#{@extra_args.join(', ')}'" \
|
43
|
+
" from path '#{@path}'"
|
44
|
+
end
|
43
45
|
end
|
44
|
-
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
## Error if path has no arguments, that controller's method required
|
48
|
+
class ExtraActionArgumentsError < ArgumentsError
|
49
|
+
def message
|
50
|
+
"Path '#{@path}' does not contain required arguments" \
|
51
|
+
" '#{@extra_args.join(', ')}' of method '#{@action}'" \
|
52
|
+
" from controller '#{@ctrl}'"
|
53
|
+
end
|
52
54
|
end
|
53
55
|
end
|
54
|
-
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
## Error for Flame::Router.find_path
|
58
|
+
class RouteNotFoundError < StandardError
|
59
|
+
def initialize(ctrl, method)
|
60
|
+
@ctrl = ctrl
|
61
|
+
@method = method
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
def message
|
65
|
+
"Route with controller '#{@ctrl}' and method '#{@method}'" \
|
66
|
+
' not found in application routes'
|
67
|
+
end
|
66
68
|
end
|
67
|
-
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
## Error for Flame::Controller.path_to
|
71
|
+
class ArgumentNotAssignedError < StandardError
|
72
|
+
def initialize(path, path_part)
|
73
|
+
@path = path
|
74
|
+
@path_part = path_part
|
75
|
+
end
|
75
76
|
|
76
|
-
|
77
|
-
|
77
|
+
def message
|
78
|
+
"Argument '#{@path_part}' for path '#{@path}' is not assigned"
|
79
|
+
end
|
78
80
|
end
|
79
|
-
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
## Error for Flame::Router.find_path
|
83
|
+
class UnexpectedTypeOfHookError < StandardError
|
84
|
+
def initialize(hook, route)
|
85
|
+
@hook = hook
|
86
|
+
@route = route
|
87
|
+
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
89
|
+
def message
|
90
|
+
"Unexpected hook-block class '#{@hook.class}'" \
|
91
|
+
" in route '#{@route}'"
|
92
|
+
end
|
91
93
|
end
|
92
94
|
end
|
93
95
|
end
|
data/lib/flame/route.rb
CHANGED
@@ -1,101 +1,103 @@
|
|
1
1
|
module Flame
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
class Router
|
3
|
+
## Class for Route in Router.routes
|
4
|
+
class Route
|
5
|
+
attr_reader :attributes
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def initialize(attrs = {})
|
8
|
+
@attributes = attrs.merge(
|
9
|
+
## Split path to parts (Array of String)
|
10
|
+
path_parts: attrs[:path].to_s.split('/').reject(&:empty?).freeze
|
11
|
+
)
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
## Get the attribute of route
|
15
|
+
## @param key [Symbol] name of attribute
|
16
|
+
def [](key)
|
17
|
+
@attributes[key]
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
## Set the attribute of route
|
21
|
+
## @param key [Symbol] name of attribute
|
22
|
+
## @param value [Object] value of attribute
|
23
|
+
def []=(key, value)
|
24
|
+
@attributes[key] = value
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
## Compare attributes for `Router.find_route`
|
28
|
+
## @param attrs [Hash] Hash of attributes for comparing
|
29
|
+
def compare_attributes(attrs)
|
30
|
+
attrs.each do |name, value|
|
31
|
+
next true if compare_attribute(name, value)
|
32
|
+
break false
|
33
|
+
end
|
32
34
|
end
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
## Assign arguments to path for `Controller.path_to`
|
37
|
+
## @param args [Hash] arguments for assigning
|
38
|
+
def assign_arguments(args = {})
|
39
|
+
self[:path_parts]
|
40
|
+
.map { |path_part| assign_argument(path_part, args) }
|
41
|
+
.unshift('').join('/').gsub(%r{\/{2,}}, '/')
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
## Extract arguments from request_parts for `execute`
|
45
|
+
## @param request_parts [Array] parts of the request (Array of String)
|
46
|
+
def arguments(request_parts)
|
47
|
+
self[:path_parts].each_with_index.with_object({}) do |(path_part, i), args|
|
48
|
+
request_part = request_parts[i]
|
49
|
+
path_part_opt = path_part[1] == '?'
|
50
|
+
next args unless path_part[0] == ':'
|
51
|
+
break args if path_part_opt && request_part.nil?
|
52
|
+
args[
|
53
|
+
path_part[(path_part_opt ? 2 : 1)..-1].to_sym
|
54
|
+
] = URI.decode(request_part)
|
55
|
+
end
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
58
|
+
## Helpers for `compare_attributes`
|
59
|
+
def compare_attribute(name, value)
|
60
|
+
case name
|
61
|
+
when :method
|
62
|
+
compare_method(value)
|
63
|
+
when :path_parts
|
64
|
+
compare_path_parts(value)
|
65
|
+
else
|
66
|
+
self[name] == value
|
67
|
+
end
|
66
68
|
end
|
67
|
-
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
def compare_method(request_method)
|
71
|
+
self[:method].upcase.to_sym == request_method.upcase.to_sym
|
72
|
+
end
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
74
|
+
def compare_path_parts(request_parts)
|
75
|
+
# p route_path
|
76
|
+
req_path_parts = self[:path_parts].select { |part| part[1] != '?' }
|
77
|
+
return false if request_parts.count < req_path_parts.count
|
78
|
+
# compare_parts(request_parts, self[:path_parts])
|
79
|
+
request_parts.each_with_index do |request_part, i|
|
80
|
+
path_part = self[:path_parts][i]
|
81
|
+
# p request_part, path_part
|
82
|
+
break false unless path_part
|
83
|
+
next if path_part[0] == ':'
|
84
|
+
break false unless request_part == path_part
|
85
|
+
end
|
84
86
|
end
|
85
|
-
end
|
86
87
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
88
|
+
## Helpers for `assign_arguments`
|
89
|
+
def assign_argument(path_part, args = {})
|
90
|
+
## Not argument
|
91
|
+
return path_part unless path_part[0] == ':'
|
92
|
+
## Not required argument
|
93
|
+
return args[path_part[2..-1].to_sym] if path_part[1] == '?'
|
94
|
+
## Required argument
|
95
|
+
param = args[path_part[1..-1].to_sym]
|
96
|
+
## Required argument is nil
|
97
|
+
fail ArgumentNotAssignedError.new(self[:path], path_part) if param.nil?
|
98
|
+
## All is ok
|
99
|
+
param
|
100
|
+
end
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|
data/lib/flame/router.rb
CHANGED
@@ -20,7 +20,9 @@ module Flame
|
|
20
20
|
|
21
21
|
## Add routes from controller to glob array
|
22
22
|
route_refine = RouteRefine.new(self, ctrl, path, block)
|
23
|
-
|
23
|
+
if Validators::ActionsValidator.new(route_refine).valid?
|
24
|
+
concat_routes(route_refine)
|
25
|
+
end
|
24
26
|
end
|
25
27
|
|
26
28
|
## Find route by any attributes
|
@@ -65,9 +67,9 @@ module Flame
|
|
65
67
|
@rest_routes ||= [
|
66
68
|
{ method: :GET, path: '/', action: :index },
|
67
69
|
{ method: :POST, path: '/', action: :create },
|
68
|
-
{ method: :GET, path: '
|
69
|
-
{ method: :PUT, path: '
|
70
|
-
{ method: :DELETE, path: '
|
70
|
+
{ method: :GET, path: '/:id', action: :show },
|
71
|
+
{ method: :PUT, path: '/:id', action: :update },
|
72
|
+
{ method: :DELETE, path: '/:id', action: :delete }
|
71
73
|
]
|
72
74
|
end
|
73
75
|
|
@@ -97,7 +99,7 @@ module Flame
|
|
97
99
|
action = path.to_sym
|
98
100
|
path = "/#{path}"
|
99
101
|
end
|
100
|
-
ArgumentsValidator.new(@ctrl, path, action).valid?
|
102
|
+
Validators::ArgumentsValidator.new(@ctrl, path, action).valid?
|
101
103
|
add_route(request_method, path, action)
|
102
104
|
end
|
103
105
|
end
|
data/lib/flame/validators.rb
CHANGED
@@ -1,91 +1,93 @@
|
|
1
1
|
require_relative 'errors'
|
2
2
|
|
3
3
|
module Flame
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
module Validators
|
5
|
+
## Compare arguments from path and from controller's action
|
6
|
+
class ArgumentsValidator
|
7
|
+
def initialize(ctrl, path, action)
|
8
|
+
@ctrl = ctrl
|
9
|
+
@path = path
|
10
|
+
@action = action
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
def valid?
|
14
|
+
## Break path for ':arg' arguments
|
15
|
+
@path_args = path_arguments(@path)
|
16
|
+
## Take all and required arguments from Controller#action
|
17
|
+
@action_args = action_arguments(@action)
|
18
|
+
## Compare arguments from path and arguments from method
|
19
|
+
no_extra_path_arguments? && no_extra_action_arguments?
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
+
private
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
## Split path to args array
|
25
|
+
def path_arguments(path)
|
26
|
+
args = path.split('/').select { |part| part[0] == ':' }
|
27
|
+
args.map { |arg| arg[1..-1].to_sym }
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
## Take args from controller's action
|
31
|
+
def action_arguments(action)
|
32
|
+
parameters = @ctrl.instance_method(action).parameters
|
33
|
+
req_parameters = parameters.select { |par| par[0] == :req }
|
34
|
+
{
|
35
|
+
all: parameters.map { |par| par[1] },
|
36
|
+
req: req_parameters.map { |par| par[1] }
|
37
|
+
}
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
def no_extra_path_arguments?
|
41
|
+
## Subtraction action args from path args
|
42
|
+
extra_path_args = @path_args - @action_args[:all]
|
43
|
+
return true if extra_path_args.empty?
|
44
|
+
fail Errors::RouterError::ExtraPathArgumentsError.new(
|
45
|
+
@ctrl, @action, @path, extra_path_args
|
46
|
+
)
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
def no_extra_action_arguments?
|
50
|
+
## Subtraction path args from action required args
|
51
|
+
extra_action_args = @action_args[:req] - @path_args
|
52
|
+
return true if extra_action_args.empty?
|
53
|
+
fail Errors::RouterError::ExtraActionArgumentsError.new(
|
54
|
+
@ctrl, @action, @path, extra_action_args
|
55
|
+
)
|
56
|
+
end
|
55
57
|
end
|
56
|
-
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
59
|
+
## Compare actions from routes and from controller
|
60
|
+
class ActionsValidator
|
61
|
+
def initialize(route_refine)
|
62
|
+
@routes_actions = route_refine.routes.map { |route| route[:action] }
|
63
|
+
@ctrl = route_refine.ctrl
|
64
|
+
@ctrl_actions = {
|
65
|
+
public: @ctrl.public_instance_methods(false),
|
66
|
+
all: @ctrl.instance_methods + @ctrl.private_instance_methods
|
67
|
+
}
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
def valid?
|
71
|
+
no_extra_routes_actions? && no_extra_controller_actions?
|
72
|
+
end
|
72
73
|
|
73
|
-
|
74
|
+
private
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
def no_extra_routes_actions?
|
77
|
+
extra_routes_actions = @routes_actions - @ctrl_actions[:public]
|
78
|
+
return true if extra_routes_actions.empty?
|
79
|
+
fail Errors::RouterError::ExtraRoutesActionsError.new(
|
80
|
+
@ctrl, extra_routes_actions
|
81
|
+
)
|
82
|
+
end
|
82
83
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
84
|
+
def no_extra_controller_actions?
|
85
|
+
extra_ctrl_actions = @ctrl_actions[:public] - @routes_actions
|
86
|
+
return true if extra_ctrl_actions.empty?
|
87
|
+
fail Errors::RouterError::ExtraControllerActionsError.new(
|
88
|
+
@ctrl, extra_ctrl_actions
|
89
|
+
)
|
90
|
+
end
|
89
91
|
end
|
90
92
|
end
|
91
93
|
end
|
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: 4.0.
|
4
|
+
version: 4.0.1
|
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
|
+
date: 2016-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -28,7 +28,7 @@ dependencies:
|
|
28
28
|
name: tilt
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.4'
|
34
34
|
- - "<"
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
|
-
- - "
|
41
|
+
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: '1.4'
|
44
44
|
- - "<"
|