moonrope 1.3.3 → 2.0.2
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 +5 -5
- data/Gemfile +9 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENCE +20 -0
- data/README.md +24 -0
- data/bin/moonrope +28 -0
- data/docs/authentication.md +114 -0
- data/docs/controllers.md +106 -0
- data/docs/exceptions.md +27 -0
- data/docs/introduction.md +29 -0
- data/docs/structures.md +214 -0
- data/example/authentication.rb +50 -0
- data/example/controllers/meta_controller.rb +14 -0
- data/example/controllers/users_controller.rb +92 -0
- data/example/structures/pet_structure.rb +12 -0
- data/example/structures/user_structure.rb +35 -0
- data/lib/moonrope.rb +5 -4
- data/lib/moonrope/action.rb +170 -40
- data/lib/moonrope/authenticator.rb +42 -0
- data/lib/moonrope/base.rb +67 -6
- data/lib/moonrope/controller.rb +4 -2
- data/lib/moonrope/doc_context.rb +94 -0
- data/lib/moonrope/doc_server.rb +123 -0
- data/lib/moonrope/dsl/action_dsl.rb +159 -9
- data/lib/moonrope/dsl/authenticator_dsl.rb +35 -0
- data/lib/moonrope/dsl/base_dsl.rb +21 -18
- data/lib/moonrope/dsl/controller_dsl.rb +60 -9
- data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
- data/lib/moonrope/dsl/structure_dsl.rb +28 -2
- data/lib/moonrope/errors.rb +13 -0
- data/lib/moonrope/eval_environment.rb +82 -3
- data/lib/moonrope/eval_helpers.rb +47 -8
- data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
- data/lib/moonrope/guard.rb +35 -0
- data/lib/moonrope/html_generator.rb +65 -0
- data/lib/moonrope/param_set.rb +11 -1
- data/lib/moonrope/rack_middleware.rb +66 -37
- data/lib/moonrope/railtie.rb +31 -14
- data/lib/moonrope/request.rb +43 -15
- data/lib/moonrope/structure.rb +100 -18
- data/lib/moonrope/structure_attribute.rb +39 -0
- data/lib/moonrope/version.rb +1 -1
- data/moonrope.gemspec +21 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/specs/action_spec.rb +455 -0
- data/spec/specs/base_spec.rb +29 -0
- data/spec/specs/controller_spec.rb +31 -0
- data/spec/specs/param_set_spec.rb +31 -0
- data/templates/basic/_action_form.erb +77 -0
- data/templates/basic/_errors_table.erb +32 -0
- data/templates/basic/_structure_attributes_list.erb +55 -0
- data/templates/basic/action.erb +168 -0
- data/templates/basic/assets/lock.svg +3 -0
- data/templates/basic/assets/reset.css +101 -0
- data/templates/basic/assets/style.css +348 -0
- data/templates/basic/assets/tool.svg +4 -0
- data/templates/basic/assets/try.js +157 -0
- data/templates/basic/authenticator.erb +52 -0
- data/templates/basic/controller.erb +20 -0
- data/templates/basic/index.erb +114 -0
- data/templates/basic/layout.erb +46 -0
- data/templates/basic/structure.erb +23 -0
- data/test/test_helper.rb +81 -0
- data/test/tests/action_access_test.rb +63 -0
- data/test/tests/actions_test.rb +524 -0
- data/test/tests/authenticators_test.rb +87 -0
- data/test/tests/base_test.rb +35 -0
- data/test/tests/controllers_test.rb +49 -0
- data/test/tests/eval_environment_test.rb +136 -0
- data/test/tests/evel_helpers_test.rb +60 -0
- data/test/tests/examples_test.rb +11 -0
- data/test/tests/helpers_test.rb +97 -0
- data/test/tests/param_set_test.rb +44 -0
- data/test/tests/rack_middleware_test.rb +131 -0
- data/test/tests/request_test.rb +232 -0
- data/test/tests/structures_param_extensions_test.rb +159 -0
- data/test/tests/structures_test.rb +398 -0
- metadata +71 -56
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Moonrope
|
|
2
|
+
module DSL
|
|
3
|
+
class AuthenticatorDSL
|
|
4
|
+
|
|
5
|
+
def initialize(authenticator)
|
|
6
|
+
@authenticator = authenticator
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def friendly_name(value)
|
|
10
|
+
@authenticator.friendly_name = value
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def description(value)
|
|
14
|
+
@authenticator.description = value
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def header(name, description = nil, options = {})
|
|
18
|
+
@authenticator.headers[name] = options.merge(:name => name, :description => description)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def error(name, description = nil, options = {})
|
|
22
|
+
@authenticator.errors[name] = options.merge(:name => name, :description => description)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def lookup(&block)
|
|
26
|
+
@authenticator.lookup = block
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def rule(name, error_code, description = nil, &block)
|
|
30
|
+
@authenticator.rules[name] = {:name => name, :error_code => error_code, :description => description, :block => block}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
require 'moonrope/structure'
|
|
2
|
+
require 'moonrope/controller'
|
|
3
|
+
require 'moonrope/authenticator'
|
|
4
|
+
|
|
1
5
|
module Moonrope
|
|
2
6
|
module DSL
|
|
3
7
|
class BaseDSL
|
|
@@ -47,24 +51,6 @@ module Moonrope
|
|
|
47
51
|
controller
|
|
48
52
|
end
|
|
49
53
|
|
|
50
|
-
#
|
|
51
|
-
# Set the authenticator for the API.
|
|
52
|
-
#
|
|
53
|
-
# @yield stores the block as the authenticator
|
|
54
|
-
#
|
|
55
|
-
def authenticator(&block)
|
|
56
|
-
@base.authenticator = block
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
#
|
|
60
|
-
# Set the default access check block.
|
|
61
|
-
#
|
|
62
|
-
# @yield stores the block as the access check
|
|
63
|
-
#
|
|
64
|
-
def default_access(value = nil, &block)
|
|
65
|
-
@base.default_access = block_given? ? block : value
|
|
66
|
-
end
|
|
67
|
-
|
|
68
54
|
#
|
|
69
55
|
# Define a new helper in the global namespace
|
|
70
56
|
#
|
|
@@ -81,6 +67,23 @@ module Moonrope
|
|
|
81
67
|
helper_instance
|
|
82
68
|
end
|
|
83
69
|
|
|
70
|
+
#
|
|
71
|
+
# Define a new authenticator
|
|
72
|
+
#
|
|
73
|
+
def authenticator(name, &block)
|
|
74
|
+
authenticator = Moonrope::Authenticator.new(name)
|
|
75
|
+
dsl = Moonrope::DSL::AuthenticatorDSL.new(authenticator)
|
|
76
|
+
dsl.instance_eval(&block) if block_given?
|
|
77
|
+
@base.authenticators[name] = authenticator
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Define a new global shared action
|
|
82
|
+
#
|
|
83
|
+
def shared_action(name, &block)
|
|
84
|
+
@base.shared_actions[name] = block
|
|
85
|
+
end
|
|
86
|
+
|
|
84
87
|
end
|
|
85
88
|
end
|
|
86
89
|
end
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'moonrope/action'
|
|
2
|
+
require 'moonrope/before_action'
|
|
3
|
+
|
|
1
4
|
module Moonrope
|
|
2
5
|
module DSL
|
|
3
6
|
class ControllerDSL
|
|
@@ -14,6 +17,31 @@ module Moonrope
|
|
|
14
17
|
# @return [Moonrope::Controller] the associated controller
|
|
15
18
|
attr_reader :controller
|
|
16
19
|
|
|
20
|
+
#
|
|
21
|
+
# Stop this controller frmo being documented
|
|
22
|
+
#
|
|
23
|
+
def no_doc!
|
|
24
|
+
@controller.doc = false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Set the friendly name for the controller
|
|
29
|
+
#
|
|
30
|
+
# @param name [String]
|
|
31
|
+
#
|
|
32
|
+
def friendly_name(string)
|
|
33
|
+
@controller.friendly_name = string
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Set the description for the controller
|
|
38
|
+
#
|
|
39
|
+
# @param description [String]
|
|
40
|
+
#
|
|
41
|
+
def description(description)
|
|
42
|
+
@controller.description = description
|
|
43
|
+
end
|
|
44
|
+
|
|
17
45
|
#
|
|
18
46
|
# Defines a new action within the controller.
|
|
19
47
|
#
|
|
@@ -28,6 +56,29 @@ module Moonrope
|
|
|
28
56
|
action
|
|
29
57
|
end
|
|
30
58
|
|
|
59
|
+
#
|
|
60
|
+
# Set the name of the authenticator to use for all actions in this controller
|
|
61
|
+
#
|
|
62
|
+
# @param name [Symbol]
|
|
63
|
+
#
|
|
64
|
+
def authenticator(name)
|
|
65
|
+
@controller.authenticator = name
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# Set the name of the access rule to use for all actions in this controller
|
|
70
|
+
#
|
|
71
|
+
# @param name [Symbol]
|
|
72
|
+
#
|
|
73
|
+
def access_rule(name)
|
|
74
|
+
if name.is_a?(Hash)
|
|
75
|
+
authenticator name.first[0]
|
|
76
|
+
access_rule name.first[1]
|
|
77
|
+
else
|
|
78
|
+
@controller.access_rule = name
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
31
82
|
#
|
|
32
83
|
# Defines a new before action within the controller.
|
|
33
84
|
#
|
|
@@ -43,14 +94,6 @@ module Moonrope
|
|
|
43
94
|
before_action
|
|
44
95
|
end
|
|
45
96
|
|
|
46
|
-
#
|
|
47
|
-
# Defines the access required for controller methods which do not
|
|
48
|
-
# define their own access.
|
|
49
|
-
#
|
|
50
|
-
def access(value = nil, &block)
|
|
51
|
-
@controller.access = block_given? ? block : value
|
|
52
|
-
end
|
|
53
|
-
|
|
54
97
|
#
|
|
55
98
|
# Defines a new helper for this controller.
|
|
56
99
|
#
|
|
@@ -61,9 +104,17 @@ module Moonrope
|
|
|
61
104
|
if @controller.base.helper(name, @controller)
|
|
62
105
|
raise Moonrope::Errors::HelperAlreadyDefined, "Helper has already been defined with name `#{name}`"
|
|
63
106
|
end
|
|
64
|
-
|
|
65
107
|
@controller.base.helpers << Moonrope::Helper.new(name, @controller, options, &block)
|
|
66
108
|
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Define a shared action which can be used by any action
|
|
112
|
+
#
|
|
113
|
+
# @param name[Symbol] the name of the shared action
|
|
114
|
+
#
|
|
115
|
+
def shared_action(name, &block)
|
|
116
|
+
@controller.shared_actions[name] = block
|
|
117
|
+
end
|
|
67
118
|
end
|
|
68
119
|
end
|
|
69
120
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Moonrope
|
|
2
|
+
module DSL
|
|
3
|
+
class FilterableDSL
|
|
4
|
+
|
|
5
|
+
def initialize(action)
|
|
6
|
+
@action = action
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def attribute(name, options = {}, &block)
|
|
10
|
+
if options[:type] == Integer || options[:type] == Float
|
|
11
|
+
# Numbers
|
|
12
|
+
options[:operators] ||= [:eq, :not_eq, :gt, :gte, :lt, :lte, :in, :not_in]
|
|
13
|
+
elsif options[:type] == String
|
|
14
|
+
# Strings
|
|
15
|
+
options[:operators] ||= [:eq, :not_eq, :starts_with, :ends_with, :in, :not_in]
|
|
16
|
+
elsif options[:type] == :timestamp
|
|
17
|
+
# Times
|
|
18
|
+
options[:operators] ||= [:eq, :not_eq, :gt, :gte, :lt, :lte]
|
|
19
|
+
else
|
|
20
|
+
# Everything else
|
|
21
|
+
options[:operators] ||= [:eq, :not_eq]
|
|
22
|
+
end
|
|
23
|
+
@action.filters[name] = options.merge(:name => name, :block => block)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'moonrope/structure_attribute'
|
|
2
|
+
|
|
1
3
|
module Moonrope
|
|
2
4
|
module DSL
|
|
3
5
|
class StructureDSL
|
|
@@ -26,6 +28,10 @@ module Moonrope
|
|
|
26
28
|
@conditions = []
|
|
27
29
|
end
|
|
28
30
|
|
|
31
|
+
def no_doc!
|
|
32
|
+
@structure.doc = false
|
|
33
|
+
end
|
|
34
|
+
|
|
29
35
|
def scope(options = {}, &block)
|
|
30
36
|
scope_dsl = self.class.new(@structure)
|
|
31
37
|
scope_dsl.options = options
|
|
@@ -35,12 +41,21 @@ module Moonrope
|
|
|
35
41
|
def group(name, &block)
|
|
36
42
|
scope_dsl = self.class.new(@structure)
|
|
37
43
|
scope_dsl.groups = [@groups, name].flatten
|
|
44
|
+
scope_dsl.conditions = @conditions
|
|
38
45
|
scope_dsl.instance_eval(&block)
|
|
39
46
|
end
|
|
40
47
|
|
|
41
|
-
def condition(condition, &block)
|
|
48
|
+
def condition(condition, description = nil, &block)
|
|
42
49
|
scope_dsl = self.class.new(@structure)
|
|
50
|
+
if condition.is_a?(Hash) && condition.size == 1
|
|
51
|
+
condition = {:authenticator => condition.first[0], :access_rule => condition.first[1]}
|
|
52
|
+
elsif condition.is_a?(Symbol)
|
|
53
|
+
condition = {:authenticator => :default, :access_rule => condition}
|
|
54
|
+
else
|
|
55
|
+
condition = {:block => condition, :description => description}
|
|
56
|
+
end
|
|
43
57
|
scope_dsl.conditions = [@conditions, condition].flatten
|
|
58
|
+
scope_dsl.groups = @groups
|
|
44
59
|
scope_dsl.instance_eval(&block)
|
|
45
60
|
end
|
|
46
61
|
|
|
@@ -61,6 +76,8 @@ module Moonrope
|
|
|
61
76
|
attribute.source_attribute = options[:source_attribute]
|
|
62
77
|
attribute.value = options[:value]
|
|
63
78
|
attribute.example = options[:eg] || options[:example]
|
|
79
|
+
attribute.doc = options[:doc]
|
|
80
|
+
attribute.mutation = options[:mutation]
|
|
64
81
|
attribute.groups = @groups
|
|
65
82
|
attribute.conditions = @conditions
|
|
66
83
|
@structure.attributes[type] << attribute
|
|
@@ -84,7 +101,16 @@ module Moonrope
|
|
|
84
101
|
|
|
85
102
|
def expansion(name, *args, &block)
|
|
86
103
|
if block_given?
|
|
87
|
-
|
|
104
|
+
if args[0].is_a?(String)
|
|
105
|
+
attrs = args[1] || {}
|
|
106
|
+
attrs[:description] = args[0]
|
|
107
|
+
elsif args[0].is_a?(Hash)
|
|
108
|
+
attrs = atrs[0]
|
|
109
|
+
else
|
|
110
|
+
attrs = {}
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
@structure.expansions[name] = attrs.merge({:block => block, :conditions => @conditions})
|
|
88
114
|
else
|
|
89
115
|
attribute(:expansion, name, *args)
|
|
90
116
|
end
|
data/lib/moonrope/errors.rb
CHANGED
|
@@ -5,6 +5,9 @@ module Moonrope
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
class HelperAlreadyDefined < Error; end
|
|
8
|
+
class MissingAuthenticator < Error; end
|
|
9
|
+
class MissingAccessRule < Error; end
|
|
10
|
+
class InvalidSharedAction < Error; end
|
|
8
11
|
|
|
9
12
|
class RequestError < Error
|
|
10
13
|
attr_reader :options
|
|
@@ -22,6 +25,16 @@ module Moonrope
|
|
|
22
25
|
end
|
|
23
26
|
end
|
|
24
27
|
|
|
28
|
+
class StructuredError < RequestError
|
|
29
|
+
def status
|
|
30
|
+
"error"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def data
|
|
34
|
+
@options
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
25
38
|
class AccessDenied < RequestError
|
|
26
39
|
def status
|
|
27
40
|
'access-denied'
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
require 'moonrope/eval_helpers'
|
|
2
|
+
require 'moonrope/eval_helpers/filter_helper'
|
|
3
|
+
|
|
1
4
|
module Moonrope
|
|
2
5
|
class EvalEnvironment
|
|
3
6
|
|
|
4
7
|
include Moonrope::EvalHelpers
|
|
8
|
+
include Moonrope::EvalHelpers::FilterHelper
|
|
5
9
|
|
|
6
10
|
# @return [Moonrope::Base] the base object
|
|
7
11
|
attr_reader :base
|
|
@@ -28,9 +32,10 @@ module Moonrope
|
|
|
28
32
|
# @param request [Moonrope::Request]
|
|
29
33
|
# @param accessors [Hash] additional variables which can be made available
|
|
30
34
|
#
|
|
31
|
-
def initialize(base, request, accessors = {})
|
|
35
|
+
def initialize(base, request, action = nil, accessors = {})
|
|
32
36
|
@base = base
|
|
33
37
|
@request = request
|
|
38
|
+
@action = action
|
|
34
39
|
@accessors = accessors
|
|
35
40
|
@default_params = {}
|
|
36
41
|
reset
|
|
@@ -46,8 +51,8 @@ module Moonrope
|
|
|
46
51
|
#
|
|
47
52
|
# @return [Object] the authenticated object
|
|
48
53
|
#
|
|
49
|
-
def
|
|
50
|
-
request ? request.
|
|
54
|
+
def identity
|
|
55
|
+
request ? request.identity : nil
|
|
51
56
|
end
|
|
52
57
|
|
|
53
58
|
#
|
|
@@ -143,6 +148,54 @@ module Moonrope
|
|
|
143
148
|
raise Moonrope::Errors::Error, "No structure found named '#{structure_name}'"
|
|
144
149
|
end
|
|
145
150
|
|
|
151
|
+
if options.delete(:return)
|
|
152
|
+
if options.empty? && action && action.returns && action.returns[:structure_opts].is_a?(Hash)
|
|
153
|
+
options = action.returns[:structure_opts]
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
if request
|
|
158
|
+
if options[:paramable]
|
|
159
|
+
if options[:paramable].is_a?(Hash)
|
|
160
|
+
options[:expansions] = options[:paramable][:expansions]
|
|
161
|
+
options[:full] = options[:paramable][:full]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
if options[:paramable] == true || options[:paramable].is_a?(Hash) && options[:paramable].has_key?(:expansions)
|
|
165
|
+
if request.params["_expansions"].is_a?(Array)
|
|
166
|
+
options[:expansions] = request.params["_expansions"].map(&:to_sym)
|
|
167
|
+
if options[:paramable].is_a?(Hash) && options[:paramable][:expansions].is_a?(Array)
|
|
168
|
+
whitelist = options[:paramable][:expansions]
|
|
169
|
+
options[:expansions].reject! { |e| !whitelist.include?(e) }
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if request.params["_expansions"] == true
|
|
174
|
+
if options[:paramable].is_a?(Hash)
|
|
175
|
+
if options[:paramable][:expansions].is_a?(Array)
|
|
176
|
+
options[:expansions] = options[:paramable][:expansions]
|
|
177
|
+
elsif options[:paramable].has_key?(:expansions)
|
|
178
|
+
options[:expansions] = true
|
|
179
|
+
end
|
|
180
|
+
else
|
|
181
|
+
options[:expansions] = true
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
if request.params["_expansions"] == false
|
|
186
|
+
options[:expansions] = nil
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if request.params.has?("_full")
|
|
192
|
+
if options[:paramable] == true || (options[:paramable].is_a?(Hash) && options[:paramable].has_key?(:full))
|
|
193
|
+
options[:full] = !!request.params["_full"]
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
146
199
|
structure.hash(object, options.merge(:request => @request))
|
|
147
200
|
end
|
|
148
201
|
|
|
@@ -169,5 +222,31 @@ module Moonrope
|
|
|
169
222
|
self.structure_for(structure_name).is_a?(Moonrope::Structure)
|
|
170
223
|
end
|
|
171
224
|
|
|
225
|
+
#
|
|
226
|
+
# Copy the list of parameters onto the given objectr
|
|
227
|
+
#
|
|
228
|
+
def copy_params_to(object, *params_to_copy)
|
|
229
|
+
if params_to_copy.first.is_a?(Hash)
|
|
230
|
+
options = params_to_copy.shift
|
|
231
|
+
if options[:from]
|
|
232
|
+
all_params = action.params.select { |_,p| p[:from_shared_action].include?(options[:from]) }
|
|
233
|
+
params_to_copy = params_to_copy + all_params.keys
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
params_to_copy.each do |param_name|
|
|
237
|
+
if param_definition = action.params[param_name]
|
|
238
|
+
if params.has?(param_name)
|
|
239
|
+
if param_definition[:apply]
|
|
240
|
+
instance_exec(object, params[param_name], ¶m_definition[:apply])
|
|
241
|
+
elsif object.respond_to?("#{param_name}=")
|
|
242
|
+
object.send("#{param_name}=", params[param_name])
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
else
|
|
246
|
+
raise Moonrope::Errors::Error, "Attempted to copy parameter #{parameter} to object but no definition exists"
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
172
251
|
end
|
|
173
252
|
end
|
|
@@ -7,29 +7,68 @@ module Moonrope
|
|
|
7
7
|
# @param type [Symbol] the type of error to raise
|
|
8
8
|
# @param message [String, Hash or Array] options to pass with the error (usually a message)
|
|
9
9
|
#
|
|
10
|
-
def error(type, message)
|
|
10
|
+
def error(type, code_or_message = nil, message = nil)
|
|
11
11
|
case type
|
|
12
|
-
when :not_found then raise(Moonrope::Errors::NotFound,
|
|
13
|
-
when :access_denied then raise(Moonrope::Errors::AccessDenied,
|
|
14
|
-
when :validation_error then raise(Moonrope::Errors::ValidationError,
|
|
15
|
-
when :parameter_error then raise(Moonrope::Errors::ParameterError,
|
|
12
|
+
when :not_found then raise(Moonrope::Errors::NotFound, code_or_message)
|
|
13
|
+
when :access_denied then raise(Moonrope::Errors::AccessDenied, code_or_message)
|
|
14
|
+
when :validation_error then raise(Moonrope::Errors::ValidationError, code_or_message)
|
|
15
|
+
when :parameter_error then raise(Moonrope::Errors::ParameterError, code_or_message)
|
|
16
|
+
when :structured_error then structured_error(code_or_message, message)
|
|
16
17
|
else
|
|
17
|
-
|
|
18
|
+
if type.is_a?(String)
|
|
19
|
+
if code_or_message.is_a?(Hash)
|
|
20
|
+
structured_error(type, nil, code_or_message)
|
|
21
|
+
else
|
|
22
|
+
structured_error(type, code_or_message, message.is_a?(Hash) ? message : {})
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
raise Moonrope::Errors::RequestError, code_or_message
|
|
26
|
+
end
|
|
18
27
|
end
|
|
19
28
|
end
|
|
20
29
|
|
|
30
|
+
#
|
|
31
|
+
# Raises a structured error.
|
|
32
|
+
#
|
|
33
|
+
# @param code [String] the code to return
|
|
34
|
+
# @param message [String] explantory text to return
|
|
35
|
+
# @param additional [Hash] additional data to return with the error
|
|
36
|
+
#
|
|
37
|
+
def structured_error(code, message, additional = {})
|
|
38
|
+
if action
|
|
39
|
+
if action.authenticator_to_use.is_a?(Moonrope::Authenticator)
|
|
40
|
+
errors = action.authenticator_to_use.errors.merge(action.errors)
|
|
41
|
+
else
|
|
42
|
+
errors = action.errors
|
|
43
|
+
end
|
|
44
|
+
if error = errors[code]
|
|
45
|
+
message = error[:description].gsub(/\{(\w+)\}/) { additional[$1.to_sym] }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
raise Moonrope::Errors::StructuredError, {:code => code, :message => message}.merge(additional)
|
|
49
|
+
end
|
|
50
|
+
|
|
21
51
|
#
|
|
22
52
|
# Return paginated information
|
|
23
53
|
#
|
|
24
54
|
def paginate(collection, max_per_page = 60, &block)
|
|
25
55
|
per_page = params.per_page || 30
|
|
26
56
|
per_page = max_per_page if per_page < 1 || per_page > max_per_page
|
|
27
|
-
paginated_results = collection.page(params.page).per(per_page)
|
|
28
|
-
set_flag :paginated, {:page => params.page, :per_page => per_page, :total_pages => paginated_results.total_pages, :total_records => paginated_results.total_count}
|
|
57
|
+
paginated_results = collection.page(params.page || 1).per(per_page)
|
|
58
|
+
set_flag :paginated, {:page => params.page || 1, :per_page => per_page, :total_pages => paginated_results.total_pages, :total_records => paginated_results.total_count}
|
|
29
59
|
paginated_results.to_a.map do |result|
|
|
30
60
|
block.call(result)
|
|
31
61
|
end
|
|
32
62
|
end
|
|
33
63
|
|
|
64
|
+
#
|
|
65
|
+
# Return information sorted by appropriate values from parameters
|
|
66
|
+
#
|
|
67
|
+
def sort(collection, &block)
|
|
68
|
+
collection = collection.order(params.sort_by => params.order)
|
|
69
|
+
set_flag :sorted, {:by => params.sort_by, :order => params.order}
|
|
70
|
+
block.call(collection)
|
|
71
|
+
end
|
|
72
|
+
|
|
34
73
|
end
|
|
35
74
|
end
|